如何在Python中实现IDA*算法来解决15个难题?

如何在Python中实现IDA*算法来解决15个难题?,python,graph-algorithm,path-finding,heuristics,sliding-tile-puzzle,Python,Graph Algorithm,Path Finding,Heuristics,Sliding Tile Puzzle,我试图用IDA*算法和曼哈顿启发式算法来解决15个难题。 我已经在这个Wikipedia页面()的伪代码中实现了该算法 以下是我目前的代码: 定义IDA(初始状态、目标状态): 初始\u节点=节点(初始\u状态) 目标\节点=节点(目标\状态) 阈值=曼哈顿启发式(初始状态、目标状态) 路径=[初始节点] 而1: tmp=搜索(路径、目标状态、0、阈值) 如果tmp==True: 返回路径,阈值 elif tmp==float('inf'): 返回错误 其他: 阈值=tmp def搜索(路径、目

我试图用IDA*算法和曼哈顿启发式算法来解决15个难题。 我已经在这个Wikipedia页面()的伪代码中实现了该算法

以下是我目前的代码:

定义IDA(初始状态、目标状态): 初始\u节点=节点(初始\u状态) 目标\节点=节点(目标\状态) 阈值=曼哈顿启发式(初始状态、目标状态) 路径=[初始节点] 而1: tmp=搜索(路径、目标状态、0、阈值) 如果tmp==True: 返回路径,阈值 elif tmp==float('inf'): 返回错误 其他: 阈值=tmp def搜索(路径、目标状态、g、阈值): 节点=路径[-1] f=g+曼哈顿启发式(节点状态、目标状态) 如果f>阈值: 返回f 如果np.array_相等(node.state、goal_state): 返回真值 最小值=浮动('inf') 对于node.nextnodes()中的n: 如果n不在路径中: path.append(n) tmp=搜索(路径、目标状态、g+1、阈值) 如果tmp==True: 返回真值 如果tmp<最小值: 最小值=tmp path.pop() 最低回报 def曼哈顿启发式(状态1、状态2): 尺寸=范围(1,长度(状态1)**2) 距离=[大小为num的计数距离(num,state1,state2)] 返回和(距离) def计数距离(编号、状态1、状态2): 位置1=np.其中(状态1=编号) 位置2=np.其中(状态2=编号) 返回距离(位置1、位置2) def曼哈顿距离(a,b): 返回abs(b[0]-a[0])+abs(b[1]-a[1]) 类节点(): 定义初始化(自我,状态): self.state=状态 def下一个节点(自身): 零=np。其中(self.state==0) y、 x=零 y=int(y) x=int(x) 向上=(y-1,x) 向下=(y+1,x) 右=(y,x+1) 左=(y,x-1) arr=[] 对于方向(上、下、右、左): 如果len(自状态)-1>=方向[0]>=0和len(自状态)-1>=方向[1]>=0: tmp=np.copy(self.state) tmp[方向[0],方向[1]],tmp[零]=tmp[零],tmp[方向[0],方向[1]] arr.append(节点(tmp)) 返回arr 我正在用一个3x3的谜题测试这段代码,这里是无限循环!由于递归,我在测试代码时遇到了一些问题

我认为错误可能在这里:
tmp=search(路径、目标状态、g+1、阈值)
(在
search
函数中)。我只在g成本值上加一个。这应该是正确的,因为我只能把一块瓷砖移到1个地方

下面介绍如何调用
IDA()
函数:

initial_state=np.array([8 7 3],[4 1 2],[0 5 6])
目标状态=np.数组([1 2 3],[8 0 4],[7 6 5])
IDA(初始状态、目标状态)

有人能帮我吗?

在您的
IDA*
实现中有几个问题。首先,变量
path
的用途是什么?我在您的代码中找到了
path
的两个用途:

  • 用作标志/map以保持已访问的板状态
  • 用作堆栈来管理递归状态
  • 但是,使用单一的数据结构不可能同时完成这两项工作。因此,您的代码需要进行的第一次修改:

    • Fix-1:将当前
      节点
      作为参数传递给
      搜索
      方法
    • Fix-2:
      标志
      应该是一个能够有效执行
      非in
      查询的数据结构
    现在,fix-1很容易,因为我们可以将当前访问节点作为搜索方法中的参数传递。对于fix-2,我们需要将
    标志的类型从
    list
    更改为
    设置为:

    • 列表
      x的平均案例复杂度为:O(n)
    • 设置
      's
      • s中
        x的平均案例复杂度为:O(1)
      • s中的
        x的最坏情况复杂度为:O(n)
    您可以查看有关的更多详细信息以了解更多详细信息

    现在,要将
    节点
    信息保存到
    集中
    ,您需要在
    节点
    类中实现
    \uuuuuuuueq\uuuuuu
    \uuuuuuhash\uuuuuuuuu
    。在下面,我附上了修改后的代码

    import timeit
    import numpy as np
    
    def IDA(initial_state, goal_state):
        initial_node = Node(initial_state)
        goal_node = Node(goal_state)
        
        threshold = manhattan_heuristic(initial_state, goal_state)
        
        #print("heuristic threshold: {}".format(threshold))
        
        loop_counter = 0
    
        while 1:
            path = set([initial_node])
            
            tmp = search(initial_node, goal_state, 0, threshold, path)
            
            #print("tmp: {}".format(tmp))
            if tmp == True:
                return True, threshold
            elif tmp == float('inf'):
                return False, float('inf')
            else:
                threshold = tmp
    
    
    def search(node, goal_state, g, threshold, path):
        #print("node-state: {}".format(node.state))
        f = g + manhattan_heuristic(node.state, goal_state)
    
        if f > threshold:
            return f
    
        if np.array_equal(node.state, goal_state):
            return True
    
        minimum = float('inf')  
        for n in node.nextnodes():
            if n not in path:
                path.add(n)
                tmp = search(n, goal_state, g + 1, threshold, path)
                if tmp == True:
                    return True
                if tmp < minimum:
                    minimum = tmp
    
        return minimum
    
    
    def manhattan_heuristic(state1, state2):
        size = range(1, len(state1) ** 2)
        distances = [count_distance(num, state1, state2) for num in size]
    
        return sum(distances)
    
    
    def count_distance(number, state1, state2):
        position1 = np.where(state1 == number)
        position2 = np.where(state2 == number)
    
        return manhattan_distance(position1, position2)
    
    
    def manhattan_distance(a, b):
        return abs(b[0] - a[0]) + abs(b[1] - a[1])
    
    
    class Node():
        def __init__(self, state):
            self.state = state
        
        def __repr__(self):
            return np.array_str(self.state.flatten())
    
        def __hash__(self):
            return hash(self.__repr__())
            
        def __eq__(self, other):
            return self.__hash__() == other.__hash__()
    
        def nextnodes(self):
            zero = np.where(self.state == 0)
            
            y,x = zero
            y = int(y)
            x = int(x)
            
            up = (y - 1, x) 
            down = (y + 1, x)
            right = (y, x + 1)
            left = (y, x - 1)
    
            arr = []
            for direction in (up, down, right, left):
                if len(self.state) - 1 >= direction[0] >= 0 and len(self.state) - 1 >= direction[1] >= 0:
                    tmp = np.copy(self.state)
                    tmp[direction[0], direction[1]], tmp[zero] = tmp[zero], tmp[direction[0], direction[1]]
                    arr.append(Node(tmp))
    
            return arr
    
    
    initial_state = np.array([[8, 7, 3],[4, 1, 2],[0, 5, 6]])
    goal_state = np.array([[1, 2, 3],[8, 0, 4],[7, 6, 5]])
    
    start = timeit.default_timer()
    is_found, th = IDA(initial_state, goal_state)
    stop = timeit.default_timer()
    
    print('Time: {} seconds'.format(stop - start))
    
    if is_found is True:
        print("Solution found with heuristic-upperbound: {}".format(th))
    else:
        print("Solution not found!")
    
    import timeit
    将numpy作为np导入
    定义IDA(初始状态、目标状态):
    初始\u节点=节点(初始\u状态)
    目标\节点=节点(目标\状态)
    阈值=曼哈顿启发式(初始状态、目标状态)
    #打印(“启发式阈值:{}”。格式(阈值))
    循环计数器=0
    而1:
    路径=设置([初始节点])
    tmp=搜索(初始节点、目标状态、0、阈值、路径)
    #打印(“tmp:{}”.format(tmp))
    如果tmp==True:
    返回真值,阈值
    elif tmp==float('inf'):
    返回False,浮点('inf')
    其他:
    阈值=tmp
    def搜索(节点、目标状态、g、阈值、路径):
    #打印(“节点状态:{}”。格式(node.state))
    f=g+曼哈顿启发式(节点状态、目标状态)
    如果f>阈值:
    返回f
    如果np.array_相等(node.state、goal_state):
    返回真值
    最小值=浮动('inf')
    对于node.nextnodes()中的n:
    如果n不在路径中:
    路径。添加(n)
    tmp=搜索(n,目标状态,g+1,阈值,路径)
    如果tmp==True:
    返回真值
    如果tmp<最小值:
    最小值=tmp
    最低回报
    def曼哈顿启发式(状态1、状态2):
    尺寸=范围(1,长度(状态1)**2)
    距离=[大小为num的计数距离(num,state1,state2)]
    返回和(距离)
    def计数距离(编号、状态1、状态2):