Как создать алгоритм из псевдокода для поиска с одинаковой стоимостью?
Как мы знаем из повседневного опыта, диагональные перемещения дешевле, чем горизонтальные + вертикальные, это становится проблемой неравномерной стоимости шага.
Таким образом, поиск единой стоимости потребуется для решения этой проблемы. Для осуществления поиска с равномерной стоимостью вам потребуется приоритетная очередь для границы.
Чтобы добавить ребенка к границе frontier.insert(item)
Извлечь предмет с минимальными затратамиTemp = frontier.extract_min()
Уменьшить стоимость предметаfrontier.decrease_key(item)
Чтобы проверить, находится ли предмет уже на границеfrontier.is_in(item)
Возвращает true, если элемент находится на границе, возвращает false, если не на границе.
Алгоритм, который я использовал для этого кода:
import collections
import copy
grid_size = 5
source = (0, 0)
destination = (4, 3)
grid = [[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0]]
class Location:
def __init__(self, p, cost=0):
self.point = p
self.parent = None
self.cost = cost
self.hash_value = self.hash_calc()
def hash_calc(self):
x, y = self.point
return str(x) + "_" + str(y)
def make_move(self, direction):
x, y = self.point
# up
if direction == 'l':
if y > 0 and grid[x][y-1] == 0:
self.point = x, y-1
self.cost = self.cost + 1
# down
elif direction == 'r':
if y < grid_size-1 and grid[x][y+1] == 0:
self.point = x, y+1
self.cost = self.cost + 1
# left
elif direction == 'u':
if x > 0 and grid[x-1][y] == 0:
self.point = x-1, y
self.cost = self.cost + 1
# right
elif direction == 'd':
if x < grid_size-1 and grid[x+1][y] == 0:
self.point = x+1, y
self.cost = self.cost + 1
# up-left
elif direction == 'ul':
if y>0 and x>0 and grid[x-1][y-1] == 0:
self.point = x-1, y-1
self.cost = self.cost + 1.5
# up-right
elif direction == 'dl':
if y>0 and x<grid_size-1 and grid[x+1][y-1] == 0:
self.point = x+1, y-1
self.cost = self.cost + 1.5
# down-left
elif direction == 'ur':
if y<grid_size-1 and x>0 and grid[x-1][y+1] == 0:
self.point = x-1, y+1
self.cost = self.cost + 1.5
# down-right
elif direction == 'dr':
if y<grid_size-1 and x<grid_size-1 and grid[x+1][y+1] == 0:
self.point = x+1, y+1
self.cost = self.cost + 1.5
self.hash_value = self.hash_calc()
print(self.point, self.cost)
def copy_location(self):
temp = Location(self.point, cost=self.cost)
temp.parent = self
return temp
def print_path(self):
ancestors = []
temp = self
while(temp.parent != None):
ancestors.append(temp.parent)
temp = temp.parent
n = len(ancestors)
for i in range(n):
temp = ancestors.pop()
print(temp.point, end='->')
print(self.point)
print('%d steps were required.\nTotal cost is %f' % (n, self.cost))
def goal_test(self):
return self.point == destination
def get_key(self):
return self.cost
class Priority_Queue:
def __init__(self):
self.capacity = 2
self.q = [None] * self.capacity
self.items = [None] * self.capacity
self.dict = {}
self.size = 0
def parent(self, i):
return int((i-1)/2)
def left(self, i):
return 2*i + 1
def right(self, i):
return 2*i + 2
def move(self, i, j):
self.q[i] = self.q[j]
self.items[i] = self.items[j]
self.dict[self.items[i].hash_value] = i
def swap(self, i, j):
self.q[i], self.q[j] = self.q[j], self.q[i]
self.items[i], self.items[j] = self.items[j], self.items[i]
self.dict[self.items[i].hash_value] = i
self.dict[self.items[j].hash_value] = j
def min_heapify(self, i):
left = self.left(i)
right = self.right(i)
smallest = i
if left < self.size and self.q[left] < self.q[i]:
smallest = left
if right < self.size and self.q[right] < self.q[smallest]:
smallest = right
if smallest != i:
self.swap(i, smallest)
self.min_heapify(smallest)
def insert(self, item):
self.size = self.size + 1
if self.size > self.capacity:
self.q = self.q + [None] * self.capacity
self.items = self.items + [None] * self.capacity
self.capacity = self.capacity * 2
i = self.size - 1
self.q[i] = item.get_key()
self.items[i] = item
self.dict[item.hash_value] = i
while i != 0 and self.q[self.parent(i)] > self.q[i]:
self.swap(i, self.parent(i))
i = self.parent(i)
def extract_min(self):
item = self.items[0]
self.move(0, self.size - 1)
self.dict.pop(item.hash_value)
self.size = self.size - 1
self.min_heapify(0)
return item
def decrease_key(self, item):
i = self.dict[item.hash_value]
if self.q[i] < item.get_key():
return
self.q[i] = item.get_key()
self.items[i] = item
while i != 0 and self.q[self.parent(i)] > self.q[i]:
self.swap(i, self.parent(i))
i = self.parent(i)
def get_min(self):
return self.items[0]
def is_in(self, item):
return item.hash_value in self.dict.keys()
# Make an initial State with source
initial_state = Location(source)
# Create an empty frontier
frontier = Priority_Queue()
frontier.insert(initial_state)
# Create an empty explored list
explored = set()
# initialize frontier with initial state
##########################################
####Solution would be here
##############Solution i Tried to solve
x = 0
children=()
Output = False
#While Output is False
while Output == False:
x = x+1
if frontier.size == 0:
print('No Solution Found !')
break
z = frontier.get_min()
explored.add(z)
#make moves
for d in ['u','d','l','r','ul','dl','ur','dr']:
children = z.copy_location()
children.make_move(d)
if children not in explored and children:
if children.goal_test() == True:
children.print_path()
Output = True
break
frontier.insert(children)
#if output is true
if Output == True:
print('Total %d states Explored !.' %(x))
break
Я хочу реализовать поиск единой стоимости здесь. Я пытался следовать псевдокоду, но мне это не удалось. Ну, это мой первый раз в переполнении стека, так что если я сделал какую-либо ошибку, пожалуйста, прости меня! я буду более осторожным со следующего раза.