Fix a_star goaltest and heuristic function

This commit is contained in:
Dominik Cupał 2021-06-23 11:52:04 +02:00
parent 5a6e5181e8
commit f07eabf522
4 changed files with 42 additions and 26 deletions

View File

@ -1,5 +1,6 @@
#!/usr/bin/python3 #!/usr/bin/python3
import copy import copy
import random
from queue import Queue, PriorityQueue from queue import Queue, PriorityQueue
from threading import Event from threading import Event
@ -44,7 +45,6 @@ class App:
if keys[pygame.K_w]: if keys[pygame.K_w]:
self.__tractor.move() self.__tractor.move()
self.__tractor.choose_action()
print(self.__tractor) print(self.__tractor)
if keys[pygame.K_n]: if keys[pygame.K_n]:
@ -87,19 +87,28 @@ class App:
self.__bot_is_running.set() self.__bot_is_running.set()
self.__tractor.run_bot_handler(self.__moves, self.__bot_is_running) self.__tractor.run_bot_handler(self.__moves, self.__bot_is_running)
if keys[pygame.K_a]:
self.auto_moving()
def update_screen(self) -> None: def update_screen(self) -> None:
pygame.display.flip() pygame.display.flip()
def quit(self) -> None: def quit(self) -> None:
pygame.quit() pygame.quit()
def auto_moving(self) -> None:
self.__tractor.choose_action()
def get_moves_by_a_star(self) -> None: def get_moves_by_a_star(self) -> None:
x, y = self.__tractor.get_position() x, y = self.__tractor.get_position()
node = Node(None, x, y, self.__tractor.get_direction(), 0, "movement", "initial state") node = Node(None, x, y, self.__tractor.get_direction(), 0, "movement", "initial state")
board = copy.deepcopy(self.__board) board = copy.deepcopy(self.__board)
self.__moves = AStar.search(PriorityQueue(), Queue(), node, x1 = random.randint(0, HORIZONTAL_NUM_OF_FIELDS)
y1 = random.randint(0, VERTICAL_NUM_OF_FIELDS)
dest = (x1, y1)
self.__moves = AStar.search_solution(PriorityQueue(), Queue(), dest, node,
lambda n=node, b=board: AStar.succ(n, b), lambda n=node, b=board: AStar.succ(n, b),
lambda n=node: AStar.goaltest(n), board) lambda d=dest, n=node: AStar.goaltest_by_coords(d, n), board)
def get_moves_by_bfs(self) -> None: def get_moves_by_bfs(self) -> None:
x, y = self.__tractor.get_position() x, y = self.__tractor.get_position()

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import copy import copy
import math
from typing import Callable, Union from typing import Callable, Union
from queue import Queue, PriorityQueue from queue import Queue, PriorityQueue
@ -10,7 +11,7 @@ from app.graphsearch import Node, Graphsearch
class PriorityItem: class PriorityItem:
def __init__(self, node: Node, priority: int): def __init__(self, node: Node, priority: float):
self.node = node self.node = node
self.priority = priority self.priority = priority
@ -46,7 +47,7 @@ class AStar(Graphsearch):
fringe.put(tmp_queue.get()) fringe.put(tmp_queue.get())
@staticmethod @staticmethod
def replace_nodes(fringe: PriorityQueue[PriorityItem], priority: int, state: tuple[int, int, float]): def replace_nodes(fringe: PriorityQueue[PriorityItem], priority: float, state: tuple[int, int, float]):
fringe_items = AStar.convert_queue_of_priority_items_with_priority_to_list(fringe) fringe_items = AStar.convert_queue_of_priority_items_with_priority_to_list(fringe)
for s in fringe_items: for s in fringe_items:
if s[:-1] == state[:-1]: if s[:-1] == state[:-1]:
@ -57,7 +58,7 @@ class AStar(Graphsearch):
break break
@staticmethod @staticmethod
def g(board: Board, node: Node) -> int: def g(board: Board, node: Node) -> float:
"""cost function""" """cost function"""
result = 0 result = 0
while node.get_node() is not None: while node.get_node() is not None:
@ -67,20 +68,28 @@ class AStar(Graphsearch):
return result return result
@staticmethod @staticmethod
def h(node: Node) -> int: def h(destination: tuple[int, int], node: Node) -> float:
"""heuristic function""" """heuristic function"""
crops_to_harvested = AMOUNT_OF_CROPS - node.get_amount_of_harvested_crops() return round(math.sqrt(abs(destination[0] - node.get_x())**2 + abs(destination[0] - node.get_y())**2), 2)
return crops_to_harvested ** 2 + crops_to_harvested * 10
@staticmethod @staticmethod
def f(board: Board, node: Node) -> int: def f(board: Board, destination: tuple[int, int], node: Node) -> float:
"""evaluation function""" """evaluation function"""
return AStar.g(board, node) + AStar.h(node) return AStar.g(board, node) + AStar.h(destination, node)
@staticmethod @staticmethod
def search(fringe: PriorityQueue, explored: Queue, istate: Node, def goaltest_by_coords(destination: tuple[int, int], item: Node) -> bool:
# print(item)
# print(destination)
if destination[0] == item.get_x() and destination[1] == item.get_y():
return True
else:
return False
@staticmethod
def search_solution(fringe: PriorityQueue, explored: Queue, destination: tuple[int, int], istate: Node,
succ: Callable[[Node, Board], list], succ: Callable[[Node, Board], list],
goaltest: Callable[[Node], bool], board: Board) -> Union[bool, list]: goaltest: Callable[[tuple[int,int], Node], bool], board: Board) -> Union[bool, list]:
print(f"Start A*") print(f"Start A*")
fringe.put(PriorityItem(istate, 0)) fringe.put(PriorityItem(istate, 0))
@ -90,7 +99,7 @@ class AStar(Graphsearch):
return False return False
item = fringe.get() item = fringe.get()
if goaltest(item.node): if goaltest(destination, item.node):
return AStar.get_all_moves(item.node) return AStar.get_all_moves(item.node)
copied_item = copy.deepcopy(item) copied_item = copy.deepcopy(item)
@ -102,7 +111,7 @@ class AStar(Graphsearch):
explored_items = AStar.convert_queue_of_priority_items_to_list(explored) explored_items = AStar.convert_queue_of_priority_items_to_list(explored)
n = Node(item.node, *state, *action) n = Node(item.node, *state, *action)
priority = AStar.f(board, n) priority = AStar.f(board, destination, n)
# print(priority) # print(priority)
if state[:-1] not in fringe_items and state[:-1] not in explored_items: if state[:-1] not in fringe_items and state[:-1] not in explored_items:
fringe.put(PriorityItem(n, priority)) fringe.put(PriorityItem(n, priority))

View File

@ -309,7 +309,7 @@ class Tractor(BaseField):
is_running.clear() is_running.clear()
def choose_action(self) -> None: def choose_action(self) -> tuple[tuple[int,int],str]:
vectors = self.__board.convert_fields_to_vectors() vectors = self.__board.convert_fields_to_vectors()
print(vectors) print(vectors)
coords = None coords = None
@ -321,6 +321,4 @@ class Tractor(BaseField):
coords = (i, j) coords = (i, j)
break break
print(coords, action) print(coords, action)
if coords is not None: return coords, action
# astar coords
pass

View File

@ -86,10 +86,10 @@ A_DO_NOTHING = "do nothing"
TYPES_OF_ACTION = [A_SOW, A_HARVEST, A_HYDRATE, A_FERTILIZE, A_DO_NOTHING] TYPES_OF_ACTION = [A_SOW, A_HARVEST, A_HYDRATE, A_FERTILIZE, A_DO_NOTHING]
# Costs fields: # Costs fields:
VALUE_OF_CROPS = 1 VALUE_OF_CROPS = 0.25
VALUE_OF_PLANT = 4 VALUE_OF_PLANT = 0.5
VALUE_OF_SAND = 7 VALUE_OF_SAND = 0.75
VALUE_OF_CLAY = 10 VALUE_OF_CLAY = 1
# Weather # Weather
W_SUNNY = 'Sunny' W_SUNNY = 'Sunny'