鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: jerryxjr1220

[技术交流] python小练习(012):象棋中“马”的日字形走法研究

[复制链接]
发表于 2018-1-23 17:42:31 | 显示全部楼层
1516700385(1).png 1516692717(1).png
步数是一样的,但是坐标不太一样。我按你的写法,除了移动顺序不同。
谢谢版主,这些题目都很有用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-11 22:26:30 | 显示全部楼层
  1. # ! /urs/bin/env python
  2. # coding=utf-8
  3. # __author__ = 'bang'  CreateDate:2018/4/11


  4. def findpath(startpoint, aimpoint):
  5.     global stepcount
  6.     global anserlist
  7.     global FLAG
  8.     FLAG += 1
  9.     horsePos = startpoint  # 记录起始位置
  10.     for i in stepTrace:
  11.         if horsePos == i[-1]:
  12.             stepcount = len(i) - 1
  13.             break
  14.     if stepcount > min(minsteplist) - 1:
  15.             FLAG -= 1
  16.             return
  17.     for history in historyPos[:]:
  18.         if horsePos == history[0]:
  19.             if stepcount > history[1]:
  20.                 FLAG -= 1
  21.                 return  # 如果该点已经出现在历史记录的点中,且步数较高,则结束
  22.             else:
  23.                 historyPos.append((horsePos, stepcount))
  24.                 historyPos.remove(history)
  25.             break       # 刷新某个点的最优步数记录
  26.     else:
  27.         historyPos.append((horsePos, stepcount))        # 位置加入历史记录
  28.     horseNextPos = [(horsePos[0] + rule[0], horsePos[1] + rule[1]) for rule in HORSERULE
  29.                     if (horsePos[0] + rule[0], horsePos[1] + rule[1]) in CHESSBOARD]       # 生成下个一可能的点
  30.     if aimpoint in horseNextPos:  # 如果目标点在下一个可能的点,则记录路径长度和路径结果
  31.         for i in stepTrace:
  32.             if i[-1] == horsePos and i not in anserlist:
  33.                 anserlist.append(i)
  34.                 minsteplist.append(len(i))
  35.                 # break
  36.         FLAG -= 1
  37.         return
  38.     else:
  39.         # 记录轨迹
  40.         for i in stepTrace[:]:
  41.             temp = i[:]
  42.             if horsePos == temp[-1]:
  43.                 for point in horseNextPos:
  44.                     temp.append(point)
  45.                     stepTrace.append(temp[:])
  46.                     temp.pop()
  47.                 stepTrace.remove(temp)
  48.                 break
  49.     for point in horseNextPos:
  50.         findpath(point, aimpoint)   # 遍历每个可能的点
  51.     FLAG -= 1
  52.     if FLAG == 0:               # 返回到最外层的函数才打印结果
  53.         for i in anserlist:         # 输出达到终点的最短路径
  54.             if len(i) == min(minsteplist):
  55.                 # i.append(aimpoint)
  56.                 print(i)
  57.         print(minsteplist)
  58.         print(len(historyPos))




  59. CHESSBOARD = tuple((i, j) for i in range(9) for j in range(10))  # 初始化象棋盘
  60. HORSERULE = tuple((i, j) for i in (-1, 1, 2, -2) for j in (-1, 1, 2, -2) if abs(i) + abs(j) == 3)  # 定义马的行棋规则
  61. startPos = (0, 0)  # input("请输入马的初始位置(以英文逗号隔开):")
  62. historyPos = [(startPos, 0)]  # 记录马曾经经过的点,以及经过该点的步数
  63. aimPos = (7, 7)  # input("请输入马的终点位置(以英文逗号隔开):")
  64. stepTrace = [[startPos]]  # 记录每次行走的路径
  65. stepcount = 0      # 记录当前步数
  66. # 判断最小步数,默认1000以内肯定能找到解
  67. minsteplist = [1000]
  68. anserlist = []
  69. FLAG = 0
  70. findpath(startPos, aimPos)
复制代码


写了个贼蠢的,貌似是先深度优先的递归,调来调去搞不明白了,总有差错,先发上来。
后来再开车的时候,想到一个开枝散叶的广度优先法,应该会改进和简洁不少。一会实现一下发出来。
等发完后,再学习各位大神的方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-11 23:57:34 | 显示全部楼层
  1. def findpath(startPt, endPt):
  2.     horseTrace = [[startPt]]
  3.     pointList = [startPt]
  4.     answerlist = []
  5.     endflag = 0
  6.     while not endflag:
  7.         lastSetpPtList = pointList[:]
  8.         tempTrace = horseTrace[:]
  9.         for i in tempTrace:
  10.             startPt = i[-1]
  11.             nextPt = [(startPt[0] + rulePt[0], startPt[1] + rulePt[1])
  12.                       for rulePt in HORSERULE
  13.                       if (startPt[0] + rulePt[0], startPt[1] + rulePt[1]) in CHESSROARD
  14.                       ]
  15.             for pt in nextPt:
  16.                 if pt not in lastSetpPtList:
  17.                     if pt not in pointList:
  18.                         pointList.append(pt)
  19.                     temp = i[:]
  20.                     temp.append(pt)
  21.                     horseTrace.append(temp[:])
  22.                     temp.pop()
  23.             horseTrace.remove(i)
  24.             if endPt in nextPt:
  25.                 for i in horseTrace:
  26.                     if i[-1] == endPt:
  27.                         horseTrace.remove(i)
  28.                         answerlist.append(i)
  29.                         endflag = 1
  30.                         break
  31.     return answerlist


  32. CHESSROARD = tuple([(i, j) for i in range(9) for j in range(10)])
  33. HORSERULE = tuple([(i, j) for i in [-1, -2, 1, 2] for j in [-1, -2, 1, 2] if abs(i) + abs(j) == 3])
  34. startPt = (0, 0)
  35. endPt = (5, 8)
  36. for i in findpath(startPt, endPt):
  37.     print(i)
  38. print(len(findpath(startPt, endPt)))
复制代码


重写了一个开枝散叶法。。。这个就颇为满意了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-12 00:25:15 | 显示全部楼层
初步总结一下,如果是求最优解(假设最短路径为n),那么一般采用需要用广度优先,遍历每个节点,效率高。这样可以进行第n次探索的时候,即找到最优解,且可以找出所有的最优解。
如果只是求解的话,当数据量很大的时候(每一级的节点很多的时候),广度优先虽然可以求得最优解,但是时间是指数级增长的。
因此用深度优先法求出其中一个解,效率可能会高一些。

以后再研究研究。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-17 10:22:08 | 显示全部楼层
请问
if 0<=p2[0]<m and 0<=p2[1]<n and chess[p2[0]][p2[1]] == 0 and p2 not in rightway:
这里的【p2 not in rightway】这个判断会不会与chess[p2[0]][p2[1]] == 0重复了呀,都是判断走没走过的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 19:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表