如何在Python中实现IDA*算法来解决15个难题?
我试图用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的谜题测试这段代码,这里是无限循环!由于递归,我在测试代码时遇到了一些问题 我认为错误可能在这里:如何在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搜索(路径、目
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
的两个用途:
- Fix-1:将当前
作为参数传递给节点
方法搜索
- Fix-2:
应该是一个能够有效执行标志
查询的数据结构非in
标志的类型从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):