关于人工智能的搜索策略实验

问题的引入与准备:

with open(r'number_shifts.txt','r')as f:
    data=f.read()
g_dict_shifts=eval(data)




#补全代码-----end-------#
print("移动规则:\n"+str(g_dict_shifts))

Layout_order = 3  # 设置阶数(棋盘大小)
Layout_len = Layout_order*Layout_order

#补全代码-----begin-------#

srcLayout=input("请输入初始布局,如'013425786':")
destLayout=input("请输入目标布局,如'123456780':")

代码输出结果:

 二、利用逆序值判断目标布局是否有解

def judge_process(srcLayout,destLayout):
    #计算初始布局和目标布局的逆序数src和dest。 
    #补全代码-----begin-------#
    srcLayout=srcLayout.strip('0')
    destLayout=destLayout.strip('0')
    s_length=len(srcLayout)
    d_length=len(destLayout)
    c=0
    d=0
    for i in range(s_length):
        for j in range(i):
            if srcLayout[j]>srcLayout[i]:
                c=c+1
    for i in range(d_length):
        for j in range(i):
            if destLayout[j]>destLayout[i]:
                d=d+1
    print('srcLayout的逆序值为:',c,'destLayout的逆序值为:',d)




    #补全代码-----end-------#
    
    #判断src和dest是否奇偶性一致
    #补全代码-----begin-------#
    if c%2==d%2:
        print('src和dest的逆序值奇偶性一致')

    else:
        print('src和dest的逆序值奇偶性不一致')
        return -1,None
judge_process(srcLayout,destLayout)

结果:

三、使用启发式算法实现位置移动:

# 启发式算法
# 返回srcLayout与destLayout两个布局中同一数字下标差之和,注意不计算数字0的下标差
def heuristic_algorithm(srcLayout,destLayout):  
    sum=0 
    #srcLayout与destLayout间的距离
    #计算srcLayout与destLayout的距离
    #补全代码-----begin-------#
    for i in srcLayout:
        if i=='0':
            continue
        else:
            sum=sum+abs(srcLayout.index(i)-destLayout.index(i))


    #补全代码-----end-------#
    return sum
heuristic_algorithm(srcLayout,destLayout)

 代码输出结果:

创建数字交换函数:
def swap_chr(nLayout, i, j, deep, destLayout):
    # 实现i位置的数字与j位置的数字交换
    #补全代码-----begin-------#
    #方法一
    nLayout=list(nLayout)
    x=nLayout[j]
    nLayout[j]=nLayout[i]
    nLayout[i]=x
    nLayout=','.join(nLayout)
    nLayout=nLayout.replace(',','')
    tmpLayout=nLayout
    #方法二
    # if i<j:
    #    tmpLayout=nLayout[:i]+nLayout[j]+nLayout[i:j]+nLayout[j+1:]
    # else:
    #    tmpLayout=nLayout[:j]+nLayout[i]+nLayout[j:i]+nLayout[i+1:]
        


    #补全代码-----end-------#
    # 计算fn,f(n)=g(n)+h(n)
    fn = heuristic_algorithm(tmpLayout, destLayout)+deep  
    return tmpLayout, fn

 四、A*算法实现:

# A*算法过程
#     stack_layouts = [] #存储所有可能的状态,OPEN表
#     lst_steps = [] #最佳搜索路径
#     g_dict_layouts={} #类似于CLOSED表,以字典形式存储,记录每个节点的父节点,以便当找到目标节点时能够快速定位实际的最短路径
#     g_dict_layouts_deep = {}#以字典形式存放每个状态的gn值
#     g_dict_layouts_fn = {}#OPEN表,以字典形式存放每个状态的fn值

#     #初始化:初始状态的相关结果
#     g_dict_layouts[srcLayout] = -1 #初始状态的父节点为-1(将初始状态加入了CLOSED表)
#     g_dict_layouts_deep[srcLayout]= 0 #初始状态的深度(gn)值为0
#     g_dict_layouts_fn[srcLayout] = g_dict_layouts_deep[srcLayout] + heuristic_algorithm(srcLayout, destLayout)
    
#     # 将当前状态存入OPEN表(stack_layouts)
#     stack_layouts.append(srcLayout)
g_dict_layouts = {}
g_dict_layouts_deep = {}
g_dict_layouts_fn = {}
def solvePuzzle_A(srcLayout, destLayout):
    src=0;dest=0
    for i in range(1,9):
        fist=0
        for j in range(0,i):
            if srcLayout[j]>srcLayout[i] and srcLayout[i]!='0':
                fist=fist+1
        src=src+fist
    for i in range(1,9):
        fist=0
        for j in range(0,i):
            if destLayout[j]>destLayout[i] and destLayout[i]!='0':
                fist=fist+1
        dest=dest+fist
    if (src%2)!=(dest%2):
        return -1, None
    g_dict_layouts[srcLayout] = -1
    g_dict_layouts_deep[srcLayout]= 1
    g_dict_layouts_fn[srcLayout] = 1 + heuristic_algorithm(srcLayout, destLayout)
    stack_layouts = []
    gn=0
    stack_layouts.append(srcLayout)
    while len(stack_layouts) > 0:
        curLayout = min(g_dict_layouts_fn, key=g_dict_layouts_fn.get)
        del g_dict_layouts_fn[curLayout]
        stack_layouts.remove(curLayout)
        if curLayout == destLayout:
            break
        ind_slide = curLayout.index("0")
        lst_shifts = g_dict_shifts[ind_slide]
        for nShift in lst_shifts:
            newLayout, fn = swap_chr(curLayout, nShift, ind_slide, g_dict_layouts_deep[curLayout] + 1, destLayout)
            if g_dict_layouts.get(newLayout) == None:
                g_dict_layouts_deep[newLayout] = g_dict_layouts_deep[curLayout] + 1
                g_dict_layouts_fn[newLayout] = fn
                g_dict_layouts[newLayout] = curLayout
                stack_layouts.append(newLayout)
    lst_steps = []
    lst_steps.append(curLayout)
    while g_dict_layouts[curLayout] != -1:
        curLayout = g_dict_layouts[curLayout]
        lst_steps.append(curLayout)
    lst_steps.reverse()
    return 0, lst_steps
# A*算法搜索过程
srcLayout=input("请输入初始布局,如'013425786':")
destLayout=input("请输入目标布局,如'123456780':")
liu, lst_steps = solvePuzzle_A(srcLayout, destLayout)
if liu != 0:
    print("目标布局不可达")
else:
    for i in range(len(lst_steps)):
        print("step #" + str(i + 1))
        print(lst_steps[i][:3])
        print(lst_steps[i][3:6])
        print(lst_steps[i][6:])
        print('当前布局为:',lst_steps[i][:3]+lst_steps[i][3:6]+lst_steps[i][6:])

输出结果:

到这里就基本上没有什么问题了,大家如果有什么问题都可以私信问我喔!

也可以关注我的公众号:风程序员

谢谢大家的关注! 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值