Commit 298095c8 by Vít Novotný

### best_search now uses stable sorting

parent ffedfdf9
 ... ... @@ -2,7 +2,7 @@ # encoding=utf-8 (pep 0263) from linked_lists import LinkedList, Cons, Nil from best_search import best_search from best_search import BestSearch biggest = 99 start = LinkedList([(2, 2), (3, 1), (2, 3), (2, 1), (3, 3), (1, 2), (3, 2), (1, 3), (1, 1)]) ... ... @@ -68,11 +68,11 @@ if __name__ == "__main__": print("Pocatecni stav: %s" % start) print("\nNalezene reseni (heuristika h1):") solution, searched, cost = next(best_search(start, biggest, is_goal, move_anyYC, h1)) solution, searched, cost = next(BestSearch(biggest, is_goal, move_anyYC, h1).search(start)) print("Prohledano %d stavu, vysledne reseni ma cenu %d." % (searched, cost)) writelist(solution.reverse()) print("\nNalezene reseni (heuristika h2):") solution, searched, cost = next(best_search(start, biggest, is_goal, move_anyYC, h2)) solution, searched, cost = next(BestSearch(biggest, is_goal, move_anyYC, h2).search(start)) print("Prohledano %d stavu, vysledne reseni ma cenu %d." % (searched, cost)) writelist(solution.reverse())
 8-posunovacka, algoritmus A* Pocatecni stav: [(2, 2), (3, 1), (2, 3), (2, 1), (3, 3), (1, 2), (3, 2), (1, 3), (1, 1)] Nalezene reseni (heuristika h1): Prohledano 170244 stavu, vysledne reseni ma cenu 26. 1: [(2, 2), (3, 1), (2, 3), (2, 1), (3, 3), (1, 2), (3, 2), (1, 3), (1, 1)] 2: [(1, 2), (3, 1), (2, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 3), (1, 1)] 3: [(1, 3), (3, 1), (2, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 2), (1, 1)] 4: [(2, 3), (3, 1), (1, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 2), (1, 1)] 5: [(2, 2), (3, 1), (1, 3), (2, 1), (3, 3), (2, 3), (3, 2), (1, 2), (1, 1)] 6: [(3, 2), (3, 1), (1, 3), (2, 1), (3, 3), (2, 3), (2, 2), (1, 2), (1, 1)] 7: [(3, 1), (3, 2), (1, 3), (2, 1), (3, 3), (2, 3), (2, 2), (1, 2), (1, 1)] 8: [(2, 1), (3, 2), (1, 3), (3, 1), (3, 3), (2, 3), (2, 2), (1, 2), (1, 1)] 9: [(1, 1), (3, 2), (1, 3), (3, 1), (3, 3), (2, 3), (2, 2), (1, 2), (2, 1)] 10: [(1, 2), (3, 2), (1, 3), (3, 1), (3, 3), (2, 3), (2, 2), (1, 1), (2, 1)] 11: [(2, 2), (3, 2), (1, 3), (3, 1), (3, 3), (2, 3), (1, 2), (1, 1), (2, 1)] 12: [(3, 2), (2, 2), (1, 3), (3, 1), (3, 3), (2, 3), (1, 2), (1, 1), (2, 1)] 13: [(3, 1), (2, 2), (1, 3), (3, 2), (3, 3), (2, 3), (1, 2), (1, 1), (2, 1)] 14: [(2, 1), (2, 2), (1, 3), (3, 2), (3, 3), (2, 3), (1, 2), (1, 1), (3, 1)] 15: [(1, 1), (2, 2), (1, 3), (3, 2), (3, 3), (2, 3), (1, 2), (2, 1), (3, 1)] 16: [(1, 2), (2, 2), (1, 3), (3, 2), (3, 3), (2, 3), (1, 1), (2, 1), (3, 1)] 17: [(2, 2), (1, 2), (1, 3), (3, 2), (3, 3), (2, 3), (1, 1), (2, 1), (3, 1)] 18: [(3, 2), (1, 2), (1, 3), (2, 2), (3, 3), (2, 3), (1, 1), (2, 1), (3, 1)] 19: [(3, 3), (1, 2), (1, 3), (2, 2), (3, 2), (2, 3), (1, 1), (2, 1), (3, 1)] 20: [(2, 3), (1, 2), (1, 3), (2, 2), (3, 2), (3, 3), (1, 1), (2, 1), (3, 1)] 21: [(1, 3), (1, 2), (2, 3), (2, 2), (3, 2), (3, 3), (1, 1), (2, 1), (3, 1)] 22: [(1, 2), (1, 3), (2, 3), (2, 2), (3, 2), (3, 3), (1, 1), (2, 1), (3, 1)] 23: [(2, 2), (1, 3), (2, 3), (1, 2), (3, 2), (3, 3), (1, 1), (2, 1), (3, 1)] 24: [(3, 2), (1, 3), (2, 3), (1, 2), (2, 2), (3, 3), (1, 1), (2, 1), (3, 1)] 25: [(3, 3), (1, 3), (2, 3), (1, 2), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)] 26: [(2, 3), (1, 3), (3, 3), (1, 2), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)] 27: [(1, 3), (2, 3), (3, 3), (1, 2), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)] Nalezene reseni (heuristika h2): Prohledano 7087 stavu, vysledne reseni ma cenu 26. 1: [(2, 2), (3, 1), (2, 3), (2, 1), (3, 3), (1, 2), (3, 2), (1, 3), (1, 1)] 2: [(1, 2), (3, 1), (2, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 3), (1, 1)] 3: [(1, 3), (3, 1), (2, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 2), (1, 1)] 4: [(2, 3), (3, 1), (1, 3), (2, 1), (3, 3), (2, 2), (3, 2), (1, 2), (1, 1)] 5: [(2, 2), (3, 1), (1, 3), (2, 1), (3, 3), (2, 3), (3, 2), (1, 2), (1, 1)] 6: [(2, 1), (3, 1), (1, 3), (2, 2), (3, 3), (2, 3), (3, 2), (1, 2), (1, 1)] 7: [(1, 1), (3, 1), (1, 3), (2, 2), (3, 3), (2, 3), (3, 2), (1, 2), (2, 1)] 8: [(1, 2), (3, 1), (1, 3), (2, 2), (3, 3), (2, 3), (3, 2), (1, 1), (2, 1)] 9: [(2, 2), (3, 1), (1, 3), (1, 2), (3, 3), (2, 3), (3, 2), (1, 1), (2, 1)] 10: [(3, 2), (3, 1), (1, 3), (1, 2), (3, 3), (2, 3), (2, 2), (1, 1), (2, 1)] 11: [(3, 3), (3, 1), (1, 3), (1, 2), (3, 2), (2, 3), (2, 2), (1, 1), (2, 1)] 12: [(2, 3), (3, 1), (1, 3), (1, 2), (3, 2), (3, 3), (2, 2), (1, 1), (2, 1)] 13: [(1, 3), (3, 1), (2, 3), (1, 2), (3, 2), (3, 3), (2, 2), (1, 1), (2, 1)] 14: [(1, 2), (3, 1), (2, 3), (1, 3), (3, 2), (3, 3), (2, 2), (1, 1), (2, 1)] 15: [(2, 2), (3, 1), (2, 3), (1, 3), (3, 2), (3, 3), (1, 2), (1, 1), (2, 1)] 16: [(3, 2), (3, 1), (2, 3), (1, 3), (2, 2), (3, 3), (1, 2), (1, 1), (2, 1)] 17: [(3, 1), (3, 2), (2, 3), (1, 3), (2, 2), (3, 3), (1, 2), (1, 1), (2, 1)] 18: [(2, 1), (3, 2), (2, 3), (1, 3), (2, 2), (3, 3), (1, 2), (1, 1), (3, 1)] 19: [(2, 2), (3, 2), (2, 3), (1, 3), (2, 1), (3, 3), (1, 2), (1, 1), (3, 1)] 20: [(3, 2), (2, 2), (2, 3), (1, 3), (2, 1), (3, 3), (1, 2), (1, 1), (3, 1)] 21: [(3, 3), (2, 2), (2, 3), (1, 3), (2, 1), (3, 2), (1, 2), (1, 1), (3, 1)] 22: [(2, 3), (2, 2), (3, 3), (1, 3), (2, 1), (3, 2), (1, 2), (1, 1), (3, 1)] 23: [(2, 2), (2, 3), (3, 3), (1, 3), (2, 1), (3, 2), (1, 2), (1, 1), (3, 1)] 24: [(2, 1), (2, 3), (3, 3), (1, 3), (2, 2), (3, 2), (1, 2), (1, 1), (3, 1)] 25: [(1, 1), (2, 3), (3, 3), (1, 3), (2, 2), (3, 2), (1, 2), (2, 1), (3, 1)] 26: [(1, 2), (2, 3), (3, 3), (1, 3), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)] 27: [(1, 3), (2, 3), (3, 3), (1, 2), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)]
 ... ... @@ -2,7 +2,7 @@ # encoding=utf-8 (pep 0263) from linked_lists import LinkedList, Cons, Nil from best_search import best_search from best_search import BestSearch biggest = 99 start = (LinkedList([("t1", 4), ("t2", 2), ("t3", 2), ("t4", 20), ... ... @@ -110,6 +110,6 @@ if __name__ == "__main__": print("Pocatecni stav: %s" % (start,)) print("\nNalezene reseni:") solution, searched, cost_ = next(best_search(start, biggest, is_goal, move_anyYC, h)) solution, searched, cost_ = next(BestSearch(biggest, is_goal, move_anyYC, h).search(start)) print("Prohledano %d stavu, vysledne reseni ma cenu %d." % (searched, cost_)) writelist(solution.reverse())
4.2_17.py.out 0 → 100644
 Rozvrh prace procesoru, algoritmus A* Pocatecni stav: ([('t1', 4), ('t2', 2), ('t3', 2), ('t4', 20), ('t5', 20), ('t6', 11), ('t7', 11)], [('idle', 0), ('idle', 0), ('idle', 0)], 0) Nalezene reseni: Prohledano 130 stavu, vysledne reseni ma cenu 24. 1: ([('t1', 4), ('t2', 2), ('t3', 2), ('t4', 20), ('t5', 20), ('t6', 11), ('t7', 11)], [('idle', 0), ('idle', 0), ('idle', 0)], 0) 2: ([('t2', 2), ('t3', 2), ('t4', 20), ('t5', 20), ('t6', 11), ('t7', 11)], [('idle', 0), ('idle', 0), ('t1', 4)], 4) 3: ([('t3', 2), ('t4', 20), ('t5', 20), ('t6', 11), ('t7', 11)], [('idle', 0), ('t2', 2), ('t1', 4)], 4) 4: ([('t4', 20), ('t5', 20), ('t6', 11), ('t7', 11)], [('t3', 2), ('t2', 2), ('t1', 4)], 4) 5: ([('t4', 20), ('t5', 20), ('t7', 11)], [('t2', 2), ('t1', 4), ('t6', 13)], 13) 6: ([('t4', 20), ('t5', 20), ('t7', 11)], [('idle', 4), ('t1', 4), ('t6', 13)], 13) 7: ([('t4', 20), ('t7', 11)], [('t1', 4), ('t6', 13), ('t5', 24)], 24) 8: ([('t7', 11)], [('t6', 13), ('t4', 24), ('t5', 24)], 24) 9: ([], [('t7', 24), ('t4', 24), ('t5', 24)], 24)
 ... ... @@ -2,7 +2,7 @@ IGNORED_PYLINT_TESTS=invalid-name missing-docstring \ redefined-variable-type too-few-public-methods duplicate-code \ too-many-locals too-many-branches too-many-locals too-many-branches too-many-arguments IGNORED_PYLINT2_TESTS=superfluous-parens IGNORED_PYLINT3_TESTS= ... ...
 ... ... @@ -3,25 +3,97 @@ """ Implementace algoritmu A* pomoci prioritni fronty """ import heapq from linked_lists import Cons, Nil def best_search(start, bound, is_goal, move_anyYC, h): searched = 0 heap = [(0, 0, start, Nil)] while True: try: f, g, node, path = heapq.heappop(heap) except IndexError: # fronta je prazdna break searched = searched + 1 path1 = Cons(node, path) if is_goal(node): yield (path1, searched, g) if f <= bound: for m, c in move_anyYC(node): if not member(m, path): heapq.heappush(heap, (g+c+h(m), g+c, m, path1)) class BestSearch(object): def __init__(self, bound, is_goal, move_anyYC, h): self.total = 0 self.bound = bound self.is_goal = is_goal self.move_anyYC = move_anyYC self.h = h def search(self, start): self.total = 0 for _, solved, sol in self.expand(Nil, (start, 0, 0), self.bound): if solved == "yes": yield sol def expand(self, path, tree, bound): if len(tree) == 3: # a leaf node, f_, g = tree if self.is_goal(node): yield (None, "yes", (Cons(node, path), self.total, f_)) if f_ <= bound: succ = Nil for m, c in self.move_anyYC(node): if not member(m, path): self.total = self.total + 1 succ = Cons((m, c), succ) if succ == Nil: yield (None, "never", None) else: trees = self.succlist(g, succ) f1 = self.bestf(trees) for tree1, solved, sol in self.expand(path, (node, f1, g, trees), bound): yield (tree1, solved, sol) elif f_ > bound: yield (tree, "no", None) else: # a tree node, f_, g, trees = tree if trees == Nil: yield (None, "never", None) else: if f_ <= bound: bound1 = min(bound, self.bestf(trees.tail)) for t1, solved1, sol1 in self.expand(Cons(node, path), trees.head, bound1): for tree1, solved, sol in self.continue_(path, (node, f_, g, Cons(t1, trees.tail)), bound, solved1, sol1): yield (tree1, solved, sol) elif f_ > bound: yield (tree, "no", None) def continue_(self, path, tree, bound, subtr_solved, sol): node, _, g, trees = tree if subtr_solved == "yes": yield (None, "yes", sol) elif subtr_solved == "no": nts = self.insert(trees.head, trees.tail) f1 = self.bestf(nts) for tree1, solved, sol in self.expand(path, (node, f1, g, nts), bound): yield (tree1, solved, sol) elif subtr_solved == "never": f1 = self.bestf(trees.tail) for tree1, solved, sol in self.expand(path, (node, f1, g, trees.tail), bound): yield (tree1, solved, sol) def succlist(self, g0, succ): if succ == Nil: return Nil n, c = succ.head g = g0 + c f_ = g + self.h(n) ts1 = self.succlist(g0, succ.tail) ts = self.insert((n, f_, g), ts1) return ts def bestf(self, trees): if trees == Nil: return self.bound return f(trees.head) def insert(self, t, ts): if f(t) <= self.bestf(ts): return Cons(t, ts) return Cons(ts.head, self.insert(t, ts.tail)) def f(tree): if len(tree) == 3: # a leaf _, f_, _ = tree else: # a tree _, f_, _, _ = tree return f_ def member(x, xs): if xs == Nil: ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!