Commit 73d8dbb4 authored by Vít Novotný's avatar Vít Novotný
Browse files

added example 4.1_9-posunovacka

parent a3debc10
#!/usr/bin/env python
# encoding=utf-8 (pep 0263)
from linked_lists import LinkedList, Cons, Nil
from best_search import best_search
biggest = 99
start = LinkedList([(2, 2), (3, 1), (2, 3), (2, 1), (3, 3), (1, 2), (3, 2), (1, 3), (1, 1)])
goal = LinkedList([(1, 3), (2, 3), (3, 3), (1, 2), (2, 2), (3, 2), (1, 1), (2, 1), (3, 1)])
def is_goal(state):
return state == goal
def move_anyYC(numbers):
if numbers == Nil:
return
xb, yb = numbers.head
if xb > 1: # pohyb mezery doleva
xl = xb - 1
new_tail = replace((xl, yb), (xb, yb), numbers.tail)
yield (Cons((xl, yb), new_tail), 1)
if xb < 3: # pohyb mezery doprava
xr = xb + 1
new_tail = replace((xr, yb), (xb, yb), numbers.tail)
yield (Cons((xr, yb), new_tail), 1)
if yb > 1: # pohyb mezery dolu
yd = yb - 1
new_tail = replace((xb, yd), (xb, yb), numbers.tail)
yield (Cons((xb, yd), new_tail), 1)
if yb < 3: # pohyb mezery nahoru
yu = yb + 1
new_tail = replace((xb, yu), (xb, yb), numbers.tail)
yield (Cons((xb, yu), new_tail), 1)
def replace(x, y, xs):
if x == xs.head:
return Cons(y, xs.tail)
return Cons(xs.head, replace(x, y, xs.tail))
def h1(state):
a, b, c, d, e, f, g, h, i = state
return (a != (1, 3)) + (b != (2, 3)) + (c != (3, 3)) + \
(d != (1, 2)) + (e != (2, 2)) + (f != (3, 2)) + \
(g != (1, 1)) + (h != (2, 1)) + (i != (3, 1))
def h2(state):
a, b, c, d, e, f, g, h, i = state
return dist(a, (1, 3)) + dist(b, (2, 3)) + dist(c, (3, 3)) + \
dist(d, (1, 2)) + dist(e, (2, 2)) + dist(f, (3, 2)) + \
dist(g, (1, 1)) + dist(h, (2, 1)) + dist(i, (3, 1))
def dist(a, b): # manhattanska vzdalenost
xa, ya = a
xb, yb = b
return abs(xa-xb) + abs(ya-yb)
def writelist(xs):
writelist_(xs, 1)
def writelist_(xs, i):
if xs != Nil:
print("%d: %s" % (i, xs.head))
writelist_(xs.tail, i+1)
# demonstracni vypis
if __name__ == "__main__":
print("8-posunovacka, algoritmus A*\n")
print("Pocatecni stav: %s" % start)
print("\nNalezene reseni (heuristika h1):")
solution, searched, cost = next(best_search(start, biggest, is_goal, move_anyYC, h1))
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))
print("Prohledano %d stavu, vysledne reseni ma cenu %d." % (searched, cost))
writelist(solution.reverse())
......@@ -8,7 +8,7 @@ from romanian_cities import graph
# horni zavora pro cenu nejlepsi cesty
biggest = 9999
def bestsearch(start):
def best_search(start):
heap = [(0, 0, start, Nil)]
while True:
try:
......@@ -48,5 +48,5 @@ def h(x):
if __name__ == "__main__":
print("Best-First Search (algoritmus A*)")
print("Veskere jednoduche cesty mezi mesty Arad a Bukurest serazene vzestupne podle ceny:")
for solution in bestsearch('Arad'):
for solution in best_search('Arad'):
print(solution)
......@@ -7,7 +7,7 @@ from romanian_cities import graph
# horni zavora pro cenu nejlepsi cesty
biggest = 9999
def bestsearch(start):
def best_search(start):
for _, solved, sol in expand(Nil, (start, 0, 0), biggest):
if solved == "yes":
yield sol
......@@ -111,5 +111,5 @@ def h(x):
if __name__ == "__main__":
print("Best-First Search (algoritmus A*)")
print("Veskere jednoduche cesty mezi mesty Arad a Bukurest serazene vzestupne podle ceny:")
for solution in bestsearch('Arad'):
for solution in best_search('Arad'):
print(solution)
......@@ -22,9 +22,6 @@ output:
python "$$FILE" > $$TEMP; \
diff "$$FILE.out" $$TEMP; \
printf '# python output test "%s" ok\n' "$$FILE"; \
else \
printf 'No output test exists for file "%s".\n' "$$FILE"; \
exit 1; \
fi; \
done
# python output test ok
......
#!/usr/bin/env python
# encoding=utf-8 (pep 0263)
""" 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))
def member(x, xs):
if xs == Nil:
return False
if x == xs.head:
return True
return member(x, xs.tail)
......@@ -10,6 +10,12 @@ class Cons(object):
self.head = x
self.tail = xs
def reverse(self):
result = Nil
for x in self:
result = Cons(x, result)
return result
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.head == other.head and self.tail == other.tail
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment