def bruteForce(root): currentTree = copy.deepcopy(root) minWidth = embedTree(currentTree) bestTree = currentTree maxSize = 16 nonLeafNodes = bestTree.getAllNonLeafNodes() flippedNodes = nodesToFlip(currentTree) if len(flippedNodes) <= maxSize: print("Computing optimal solution with", len(flippedNodes), "flipped nodes...") perms = [ list(itertools.permutations(node.children)) for node in flippedNodes ] widths = defaultdict(int) allOrders = itertools.product(*perms) for ordering in allOrders: # Note that currentTree is not copied when we check new orderings, # so the nodes in flippedNodes are always part of currentTree. for i in range(len(perms)): flippedNodes[i].children = ordering[i] newWidth = embedTree(currentTree) widths[newWidth] += 1 if newWidth < minWidth: minWidth = newWidth bestTree = copy.deepcopy(currentTree) print("Number of ways to achieve each width:", widths) else: print("Error! Tree is too large for brute force (", len(perms), "flipped nodes ).") return bestTree
def search(root, prob): currentTree = copy.deepcopy(root) currentCost = embedTree(currentTree) startTemp = currentCost / 100 totalSteps = 5000.0 tempDecrease = startTemp / totalSteps currentTemp = startTemp flippedNodes = nodesToFlip(currentTree) while currentTemp > 0: flipNode = random.choice(flippedNodes) # Save the old ordering oldChildren = flipNode.children # Generate a new random ordering, and compute the new cost newChildren = [c for c in flipNode.children] if (len(newChildren) == 2): newChildren = [newChildren[1], newChildren[0]] else: random.shuffle(newChildren) flipNode.children = newChildren newCost = embedTree(currentTree) # print(currentCost, newCost, currentTemp, prob(currentCost, newCost, currentTemp)) if (random.random() < prob(currentCost, newCost, currentTemp)): # If keep, update the cost currentCost = newCost else: # Else, return to the old ordering flipNode.children = oldChildren currentTemp -= tempDecrease return currentTree
def shapeAndStoreIfBetter(temp, shapes): embedTree(temp) shape = Shape(temp) if not shape.type in shapes or shapes[shape.type].better(shape): newTree = copy.copy(temp) newTree.children = copy.copy(temp.children) shape.tree = newTree shapes[shape.type] = shape
def embedTest(): n0 = Node(0, 8, []) n1 = Node(1, 6, [n0]) n2 = Node(2, 4, []) n3 = Node(3, 2, [n2, n1]) n4 = Node(4, 4, []) n5 = Node(5, 6, []) n6 = Node(6, 8, []) n7 = Node(7, 4, [n5, n6]) n8 = Node(8, 2, [n4, n7]) n9 = Node(9, 0, [n3, n8]) n9.fillStats() tree = heuristics.identity(n9) width = embedTree(tree) print("Width: " + str(width)) print("White: " + str(tree.stats.whitespace)) tree.printMe(0) save_img(tree, "test")
def whitespaceOrder(node): for c in node.children: whitespaceOrder(c) if len(node.children) > 4: print("Warning going to try more than " + str(len(node.children)) + "! permutations") #Well do permutations if stable stable = copy.copy(node.children) best = copy.copy(stable) bestWidth = embedTree(node) bestWhitespace = node.stats.whitespace bestFlip = None for i in range(0, len(stable) + 1): for flipPerm in itertools.combinations(stable, i): for n in flipPerm: flip(n) for perm in itertools.permutations(stable): perm = list(perm) node.children = perm permWidth = embedTree(node) permWhitespace = node.stats.whitespace if permWhitespace < bestWhitespace or ( permWhitespace == bestWhitespace and permWidth < bestWidth): best = copy.copy(perm) bestWidth = permWidth bestWhitespace = permWhitespace bestFlip = flipPerm node.children = stable for n in flipPerm: flip(n) node.children = best if bestFlip: for n in bestFlip: flip(n)
def runTests(id, tree, tests): results = [] print("Running " + str(id), end="\t") print("Lower bound: ", lowerBound(tree)) for heuristic, name in tests: start = time.process_time() resultTree = heuristic(tree) resultWidth = embedTree(resultTree) end = time.process_time() results.append((name, resultWidth)) if not suppressImage: save_img(resultTree, imagePath + name + "_" + str(id)) print(name + " took " + "{:.2f}".format(end - start) + "s", end=" ") print("") sys.stdout.flush() return results
def test(): n0 = Node(0, 6, []) n1 = Node(1, 8, []) n2 = Node(2, 4, [n0, n1]) n3 = Node(3, 8, []) n4 = Node(4, 10, []) n5 = Node(5, 6, [n3, n4]) n6 = Node(6, 12, []) n7 = Node(7, 2, [n2, n5, n6]) n8 = Node(8, 4, []) n9 = Node(9, 6, []) n10 = Node(10, 2, [n8, n9]) n11 = Node(11, 0, [n7, n10]) n11.fillStats() tree = heuristics.nodesToLeaf(n11) width = embedTree(tree) print("Width: " + str(width)) print("White: " + str(tree.stats.whitespace)) bottomRect, topRect = approximateWithTwoRects(tree.stats.leftBorder, tree.stats.rightBorder) print("BottomRect: " + str(bottomRect)) print("TopRect: " + str(topRect)) s = Shape(bottomRect, topRect, tree) print(str(s.type)) tree.printMe(0) #tree.printMe(0, lambda n : str((n.dNode, str(n))) ) #tree.printMe(0, lambda n : str((n.dNode, str(n.stats))) ) save_img(tree, "test")
def branch_and_bound(tree): currentTree = copy.deepcopy(root) minWidth = embedTree(currentTree) nonLeafNodes = currentTree.getAllNonLeafNodes()
def smallTest(): n0 = Node(0, 10, []) n1 = Node(1, 10, []) n2 = Node(2, 8, [n0, n1]) n3 = Node(3, 8, []) n4 = Node(4, 6, [n3]) n5 = Node(5, 4, []) n6 = Node(6, 2, [n4, n5]) n7 = Node(7, 0, [n2, n6]) n7.fillStats() tree = heuristics.tetris(n7) width = embedTree(tree) print("Width: " + str(width)) print("White: " + str(tree.stats.whitespace)) s = Shape(tree) print("BottomRect: " + str(s.bottomRect)) print("TopRect: " + str(s.topRect)) print(str(s.type)) tree.printMe(0) print("Shape tests--------------------------------") r0 = Rect(10, 0, 0, 10) r1 = Rect(20, 0, 10, 30) print(s.getType(r1, r0)) r0.left = 10 r0.right = 20 print(s.getType(r1, r0)) r0.left = 20 r0.right = 30 print(s.getType(r1, r0)) r0.left = 1 r0.right = 29 print(s.getType(r1, r0)) r0.left = 0 r0.right = 30 print(s.getType(r1, r0)) r1.left = 0 r1.right = 10 print(s.getType(r1, r0)) r1.left = 10 r1.right = 20 print(s.getType(r1, r0)) r1.left = 10 r1.right = 30 print(s.getType(r1, r0)) r1.left = 1 r1.right = 29 print(s.getType(r1, r0)) r1.left = 0 r1.right = 30 print(s.getType(r1, r0)) r1.left = 10 r1.right = 50 print(s.getType(r1, r0)) r0.left = 20 r0.right = 60 print(s.getType(r1, r0))