Как создать алгоритм из псевдокода для поиска с одинаковой стоимостью?

Как мы знаем из повседневного опыта, диагональные перемещения дешевле, чем горизонтальные + вертикальные, это становится проблемой неравномерной стоимости шага.

Таким образом, поиск единой стоимости потребуется для решения этой проблемы. Для осуществления поиска с равномерной стоимостью вам потребуется приоритетная очередь для границы.

Чтобы добавить ребенка к границе 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

Я хочу реализовать поиск единой стоимости здесь. Я пытался следовать псевдокоду, но мне это не удалось. Ну, это мой первый раз в переполнении стека, так что если я сделал какую-либо ошибку, пожалуйста, прости меня! я буду более осторожным со следующего раза.

0 ответов

Другие вопросы по тегам