最近用python写了个自动拼图游戏,内部算法使用的是A*算法。
功能为打开一张图片,选择图片分割的维数和图片空缺的位置,然后自动打乱生成新的图片,然后再恢复。
把起点加入 open表。
重复如下过程:
a. 遍历 open表,查找 F 值最小的节点,把它作为当前要处理的节点。
b. 把这个节点移到 close表。
c. 对当前方格的 4个方向相邻方格进行操作:
◆ 如果它是不可抵达的或者它在 close表中,忽略它。
◆ 如果它不在 open表中,把它加入 open表,并且把当前方格设置为它的父亲,记录该方格的 F,G 和H值。
◆ 如果它已经在 open表中,检查这条路径 ( 即经由当前方格到达它那里 ) 是否更好,用 H值作参考。更小的H值表示这是更好的路径。如果是这样,把它的父亲设置为当前方格,并重新计算它的 G 、H和 F 值。
d. 判断是否出现以下情况,是就停止跳出循环:
◆ 把终点加入到了 open表中,此时路径已经找到了,或者
◆ 查找终点失败,并且 open表是空的,此时没有路径。
这是A*算法的代码,主要的就是这个,其他的只是画界面和呈现出来而已。
def run_Axing():
maxcount=10000+m*m*n*n
# 1. 把起始格添加到开启列表。
openList[0]=li0[:]
cost[0]=H_cost(li_goal,openList[0])
before[0]=0
Gn = 0
# add_open(st[0])
# 2.重复如下的工作:
while len(closeList)<10000:
# a) 寻找开启列表中H值最低的格子。我们称它为当前格。
mc = cost.index(min(cost))
if cmp(openList[mc][:],li_goal[:])==0:
return mc
x = openList[mc].index(0) + 1
# b) 把它切换到关闭列表。
closeList.append(openList[mc][:])
cost[mc]=maxcount
# del openList[mc]
# del cost[mc]
# c) 对相邻的8格中的每一个进行以下操作
for i in range(0, 4):
if bool_rules(x, x + move[i]):
temp = turn(x, x + move[i], openList[mc][:])[:]
if closeList.count([temp]) == 0: # 如果它不可通过或者已经在关闭列表中,略过它。
if openList.count([temp]) == 0:
openList.append(temp) # 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的H值。
c = H_cost(li_goal, openList[-1])+Gn
cost.append(c)
before.append(mc)
# 如果它已经在开启列表中,用H值为参考检查新的路径是否更好。
# 更低的H值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,
# 并且重新计算这一格的H值。
else:
t = openList.index(temp)
c = H_cost(li_goal, openList[t])+Gn
if c < cost[t]:
cost[t]=c
before[t] = mc
Gn += 1
return -1
H值计算函数,下面给出两种,可以自己试试效果:
def H_cost1(li1,li2):#当前搜索点到目标点的估计代价
cost=0
for i in range(0,len(li1)):
cost+=abs(li1[i]-li2[i])
return cost
def H_cost2(li1,li2):#当前搜索点到目标点的估计代价
#两个点的距离用欧式距离
cost=0
for i in range(0,len(li1)):
p = li1.index(i)
q = li2.index(i)
if p!=q:
x1=int(p/m);x2=int(q/m);y1=p-m*x1;y2=q-m*x2;
cost +=math.sqrt((x1-x2)**2+(y1-y2)**2)
return cost
代码下载链接:https://download.csdn.net/download/czq_0768/11159083
有什么欢迎的回应讨论。