Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.33 KB | None | 0 0
  1. from __future__ import nested_scopes, print_function
  2.  
  3. import bisect
  4. import numpy
  5.  
  6. from collections import namedtuple
  7. from itertools import combinations
  8.  
  9. Num = namedtuple("Num", ["value", "i"])
  10.  
  11. # This implements the Karmarkar-Karp heuristic for partitioning a set
  12. # in two, i.e. into two disjoint subsets s.t. their sums are
  13. # approximately equal. It produces only one result, in O(N log N)
  14. # time. A remarkable property is that it loves large sets: in
  15. # general, the more numbers you feed it, the better it does.
  16.  
  17. def partition(nums):
  18. nums = sorted(Num(num, i) for i, num in enumerate(nums))
  19.  
  20. N = len(nums)
  21. connections = [[] for _ in range(N)]
  22.  
  23. while len(nums) > 1:
  24. bigger = nums.pop()
  25. smaller = nums.pop()
  26.  
  27. # Force these into different sets, by "drawing a
  28. # line" connecting them.
  29. i, j = bigger.i, smaller.i
  30. connections[i].append(j)
  31. connections[j].append(i)
  32.  
  33. diff = bigger.value - smaller.value
  34. assert diff >= 0
  35. bisect.insort(nums, Num(diff, i))
  36.  
  37. # Now sorted contains only 1 element x, and x.value is
  38. # the difference between the subsets' sums.
  39.  
  40. # Theorem: The connections matrix represents a spanning tree
  41. # on the set of index nodes, and any tree can be 2-colored.
  42. # 2-color this one (with "colors" 0 and 1).
  43.  
  44. index2color = [None] * N
  45.  
  46. def color(i, c):
  47. if index2color[i] is not None:
  48. assert index2color[i] == c
  49. return
  50.  
  51. index2color[i] = c
  52.  
  53. for j in connections[i]:
  54. color(j, not c)
  55.  
  56. color(0, 0)
  57.  
  58. # Partition the indices by their colors.
  59. subsets = [[], []]
  60.  
  61. for i, color in enumerate(index2color):
  62. subsets[color].append(i)
  63.  
  64. return subsets
  65.  
  66. def two_sort_optimal(bricks):
  67. indexes_1, indexes_2 = partition(bricks)
  68.  
  69. tower_1 = [bricks[x] for x in indexes_1]
  70. tower_2 = [bricks[x] for x in indexes_2]
  71.  
  72. return tower_1, tower_2
  73.  
  74. def tower_greed(bricks, n_tower):
  75. bricks.sort(reverse=True)
  76.  
  77. towers = [[] for _ in range(n_tower)]
  78. heights = [0] * n_tower
  79.  
  80. for brick in bricks:
  81. lowest = heights.index(min(heights))
  82. towers[lowest].append(brick)
  83. heights[lowest] += brick
  84.  
  85. return towers
  86.  
  87. def tower_build(bricks, n_tower):
  88. if n_tower == 2:
  89. return two_sort_optimal(bricks)
  90.  
  91. towers = tower_greed(bricks, n_tower)
  92.  
  93. heights = [sum(i) for i in towers]
  94. print("First pass stdev:", numpy.std(heights))
  95.  
  96. def reshuffle(tower_1, tower_2):
  97. old_diff = abs(sum(tower_1) - sum(tower_2))
  98.  
  99. new_tower_1, new_tower_2 = two_sort_optimal(tower_1 + tower_2)
  100.  
  101. new_diff = abs(sum(new_tower_1) - sum(new_tower_2))
  102.  
  103. if old_diff <= new_diff:
  104. return False
  105.  
  106. tower_1[:] = new_tower_1
  107. tower_2[:] = new_tower_2
  108.  
  109. return True
  110.  
  111. while True:
  112. towers.sort(key=sum)
  113.  
  114. shuffles = [reshuffle(t1, t2) for t1, t2 in combinations(towers, 2)]
  115.  
  116. if not any(shuffles):
  117. break
  118.  
  119. return towers
  120.  
  121. if __name__ == "__main__":
  122. with open('buildingSite3.txt') as f:
  123. numberTowers = 23
  124. bricks = [int(line.strip()) for line in f]
  125.  
  126. towers = tower_build(bricks,numberTowers)
  127.  
  128. heights = [sum(i) for i in towers]
  129. print("Final stdev:", numpy.std(heights))
  130. print(towers)
  131. print(*map(sum, towers))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement