Python 3.x 寻径:一颗从A到B的长度与从B到A的长度不同的恒星

Python 3.x 寻径:一颗从A到B的长度与从B到A的长度不同的恒星,python-3.x,a-star,sliding-tile-puzzle,Python 3.x,A Star,Sliding Tile Puzzle,我正在用曼哈顿距离为8号拼图实现A星算法。[溶液呈螺旋状] 1 2 3 8 0 4 7 6 5 在某些情况下,从A到B的步骤数与从B到A的步骤数不同 我认为这是因为当它们具有相同的成本时,它不会在开放列表中选择相同的状态,因此不会扩展相同的节点 从 使用曼哈顿距离,两者的值相同。 我应该用相同的值探索所有路径吗? 或者我应该改变启发式,让它成为一种平局破坏者 下面是代码的相关部分 def solve(self): cost = 0 priority = 0 self.

我正在用曼哈顿距离为8号拼图实现A星算法。[溶液呈螺旋状]

1 2 3
8 0 4
7 6 5
在某些情况下,从A到B的步骤数与从B到A的步骤数不同

我认为这是因为当它们具有相同的成本时,它不会在开放列表中选择相同的状态,因此不会扩展相同的节点

使用曼哈顿距离,两者的值相同。 我应该用相同的值探索所有路径吗? 或者我应该改变启发式,让它成为一种平局破坏者

下面是代码的相关部分

 def solve(self):
    cost = 0
    priority = 0
    self.parents[str(self.start)] = (None, 0, 0)
    open = p.pr() #priority queue
    open.add(0, self.start, cost)
    while open:
       current = open.get()
       if current == self.goal:
        return self.print_solution(current)
       parent = self.parents[str(current)]
       cost = self.parents[str(current)][2] + 1
       for new_state in self.get_next_states(current):
         if str(new_state[0]) not in self.parents or cost < self.parents[str(new_state[0])][2]:
           priority = self.f(new_state) + cost
           open.add(priority, new_state[0], cost)
           self.parents[str(new_state[0])] = (current, priority, cost)
def求解(自):
成本=0
优先级=0
self.parents[str(self.start)]=(无,0,0)
open=p.pr()#优先级队列
打开。添加(0,自启动,成本)
打开时:
当前=打开。获取()
如果当前==自我目标:
返回自打印解决方案(当前)
父项=自身。父项[str(当前)]
成本=自己的父母[str(当前)][2]+1
对于self中的新状态。获取下一个状态(当前):
如果str(新_状态[0])不在self.parents中或成本
在浪费了这么多时间重新编写我的“solve”函数后,我用了很多不同的方法,但都没有付出任何代价, 我终于找到了问题所在

 def get_next_states(self, mtx, direction):
    n = self.n
    pos = mtx.index(0)
    if  direction != 1 and pos < self.length and (pos + 1) % n: 
      yield (self.swap(pos, pos + 1, mtx),pos, 3)
    if  direction != 2 and pos < self.length - self.n:
      yield (self.swap(pos, pos + n, mtx),pos, 4)
    if  direction != 3 and pos > 0 and pos % n:
     yield (self.swap(pos, pos - 1, mtx),pos, 1)
    if  direction != 4 and pos > n - 1:
     yield (self.swap(pos, pos - n, mtx),pos, 2)
def get_next_状态(自身、mtx、方向):
n=self.n
pos=mtx.索引(0)
如果方向正确!=1和位置<自身长度和(位置+1)%n:
收益率(自交换(pos,pos+1,mtx),pos,3)
如果方向正确!=2和位置0和位置%n:
收益率(自交换(pos,pos-1,mtx),pos,1)
如果方向正确!=4和位置>n-1:
收益率(自交换(pos,pos-n,mtx),pos,2)
这是在这个功能。最后一个if用于“if 4和pos>n:” 所以有未经探索的州。。 “1”的2天


它将教会我做更多的单元测试

我不确定我是否理解您在示例中所说的
A->B
B->A
。您是否正在从目标到显示的“发件人”位置进行搜索?其他图表如何与这些搜索相关?我看不出你的A*代码有任何明显的错误,但因为它不是完全独立的,所以我不能实际运行它来查看是否有任何细微的错误。启发式中的关系不应该是问题,只要它仍然存在。如果有多个解决方案,它可能会找到任何解决方案,但它们的长度都相同。@Blckknght,是的,这就是我的意思。从进球到我展示的“From”位置。所以我不需要找到一种管理关系的方法,因为曼哈顿距离是可以接受的,那么我的代码有什么问题吗?我将清理代码并发布项目的github链接。我尝试使用f=0而不是曼哈顿距离,并且尝试删除if current==self.goal:return self.print_solution(current)以获得所有可能的解决方案。两者都不会改变什么。我相信问题出在问题中所贴的功能上,可能在自我父母身上。以下是完整的代码:
 def get_next_states(self, mtx, direction):
    n = self.n
    pos = mtx.index(0)
    if  direction != 1 and pos < self.length and (pos + 1) % n: 
      yield (self.swap(pos, pos + 1, mtx),pos, 3)
    if  direction != 2 and pos < self.length - self.n:
      yield (self.swap(pos, pos + n, mtx),pos, 4)
    if  direction != 3 and pos > 0 and pos % n:
     yield (self.swap(pos, pos - 1, mtx),pos, 1)
    if  direction != 4 and pos > n - 1:
     yield (self.swap(pos, pos - n, mtx),pos, 2)