Add bfs algorithm to find shortest for all targets

This commit is contained in:
s464852 2022-04-07 20:39:55 +02:00
parent 2725517368
commit 7b1e1d92c1
2 changed files with 57 additions and 14 deletions

View File

@ -6,25 +6,38 @@ from collections import defaultdict
class Instance:
def __init__(self):
self.graph = defaultdict(list)
self.directions_dict = defaultdict(list)
def config(self, fields):
adjacency_list = self.generate_graph()
fields_to_visit = self.generate_target_fields(fields)
print("Adjacency list: " + str(dict(adjacency_list)))
print("List of targets: " + str(fields_to_visit))
adjacency_list = self.__generate_graph()
nodes_to_visit = self.generate_target_fields(fields)
shortest_path_bfs = self.generate_shortest_path_for_all_targets_bfs(nodes_to_visit)
def add_edge(self, u, v):
print("Adjacency list: " + str(dict(adjacency_list)))
print("List of targets: " + str(nodes_to_visit))
print("The shortest path found by bfs algorithm: " + str(shortest_path_bfs))
def generate_shortest_path_for_all_targets_bfs(self, nodes_to_visit):
shortest_bfs_path = []
start_node = 0
for target_node in nodes_to_visit:
shortest_bfs_path.extend(self.__shortest_path_bfs(start_node, target_node)[1:])
start_node = target_node
return shortest_bfs_path
# private
def __add_edge(self, u, v):
self.graph[u].append(v)
def generate_graph(self):
def __generate_graph(self):
width = settings.Field.horizontal_count()
height = settings.Field.vertical_count()
for i in range(height):
for j in range(width):
point = i * width + j
# point_row = math.floor(point/width)
# point_column = point % width
point_left = i * width + j - 1
point_left_column = point_left - width * i
point_right = i * width + j + 1
@ -35,16 +48,45 @@ class Instance:
point_down_row = math.floor(point_down / width)
if point_left_column >= 0:
self.add_edge(point, point_left)
self.__add_edge(point, point_left)
if point_right_column > 0:
self.add_edge(point, point_right)
self.__add_edge(point, point_right)
if point_up_row >= 0:
self.add_edge(point, point_up)
self.__add_edge(point, point_up)
if point_down_row < height:
self.add_edge(point, point_down)
self.__add_edge(point, point_down)
return self.graph
def __shortest_path_bfs(self, start_node, target_node):
path_list = [[start_node]]
path_index = 0
visited_nodes = {start_node}
if start_node == target_node:
return path_list[0]
while path_index < len(path_list):
current_path = path_list[path_index]
prev_node = current_path[-1]
next_nodes = self.graph[prev_node]
if target_node in next_nodes:
current_path.append(target_node)
return current_path
for next_node in next_nodes:
if not next_node in visited_nodes:
new_path = current_path[:]
new_path.append(next_node)
path_list.append(new_path)
visited_nodes.add(next_node)
path_index += 1
return False
# static
@staticmethod
def generate_target_fields(fields):
width = settings.Field.horizontal_count()

View File

@ -1,5 +1,6 @@
from enum import Enum
class Priorities(Enum):
SMALLEST = 0
MEDIUM = 2
@ -8,7 +9,7 @@ class Priorities(Enum):
@staticmethod
def whatIsFirst(_prio1, _prio2):
if(_prio1 > _prio2):
if (_prio1 > _prio2):
return _prio1
elif _prio2 >= _prio1:
return _prio2
@ -27,6 +28,7 @@ class Trailer:
def use(self):
self.capacity -= 0.1
class Fertilizer(Trailer): # do nawożenia
def __init__(self):
super(Fertilizer, self).__init__("Fertilizer", Priorities.SMALLEST, 100) # parametry do uzupełnienia
@ -45,4 +47,3 @@ class Harvest(Trailer): # do zbierania
class Sow(Trailer): # do siania
def __init__(self):
super(Sow, self).__init__("Sow", Priorities.HIGHEST, 200) # parametry do uzupełnienia