鱼C论坛

 找回密码
 立即注册
查看: 2625|回复: 8

[已解决]求教一个关于马踏棋盘的问题,希望好心人帮忙

[复制链接]
发表于 2018-10-23 15:59:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
下面是我写的马踏棋盘问题,运行起来总是有问题,会出现第二张图那种情况?请问有大神帮忙指出代码哪里有问题么?
最佳答案
2018-10-29 12:30:45
大腿壮 发表于 2018-10-24 08:30
倒是不急,就是不知道哪里有问题挺烦人的。。。希望能解答一下疑惑,感谢层主

变量名与函数小修改。board 去记录走过的路,tour 把坐标记下来。原本的 direct 我换了,不然真的是跑太慢了。主要的架构是 mark, find_path, unmark。其他得看题目的需求。这个大概需要两分钟,没有优化的就是这样。优化的不想搞
  1. def printBoard(board):
  2.     for each in board:
  3.         for i in each:
  4.             print(f'{i:3d}', end = ' ')
  5.         print()

  6. def mark(board, pos, n):
  7.     board[pos[0]][pos[1]] = n

  8. def unmark(board, pos):
  9.     board[pos[0]][pos[1]] = 0

  10. def isPossible(board, x, y, n):
  11.     return 0 <= x < n and 0 <= y < n and board[x][y] ==  0

  12. def knights_tour(board,pos):
  13.     mark(board, pos, 1)
  14.     tour = [pos]
  15.     N = len(board)
  16.     L = N * N
  17.     moves = [(1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1),(-2,1),(-1,2)]
  18.    
  19.     def find_path(board, pos, dep):
  20.         for i in moves:
  21.             next_pos = (pos[0] + i[0], pos[1] + i[1])
  22.             
  23.             if isPossible(board, *next_pos, N):
  24.                 mark(board, next_pos, dep)
  25.                 tour.append(next_pos)
  26.                 if dep == L:
  27.                     return 1
  28.                 if find_path(board, next_pos, dep+1) == 1:
  29.                     return 1
  30.                 else:
  31.                     unmark(board, next_pos)
  32.                     tour.pop()
  33.         return 0

  34.     if find_path(board, pos, 2):
  35.         print("Success!")
  36.         print(tour,'\n')
  37.         printBoard(board)
  38.     else:
  39.         print("Failed!")
  40.     return tour

  41. def create_chessboard(n):
  42.     return [[0]*n for i in range(n)]

  43. board = create_chessboard(8)
  44. knights_tour(board,(0,0))
复制代码

整个的代码图

整个的代码图

打印了一下mark中的pos位置,发现(6,7)之后的下一个居然是(0,7),按照走的方向不可能出现的啊,感觉很奇怪

打印了一下mark中的pos位置,发现(6,7)之后的下一个居然是(0,7),按照走的方向不可能出现的啊,感觉很奇怪
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-10-23 16:03:59 | 显示全部楼层
可以发代码吗?
图贴旁边的 <>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-23 16:13:34 | 显示全部楼层
  1. direct = [[-2,-1],[-1,-2],[1,-2],[2,-1],[2,1],[1,2],[-1,2],[-2,1]]
  2. #走过的位置标记为1
  3. def mark(maze,pos):
  4.         maze[pos[0]][pos[1]] = 1
  5.         print(pos)
  6. #判断下一步位置的条件
  7. def possible(maze,pos):
  8.         return (pos[0] in range(8)) and (pos[1] in range(8)) and (maze[pos[0]][pos[1]] ==  0)
  9. #结束条件
  10. def end_path(maze):
  11.         for m in maze:
  12.                 if 0 in m:
  13.                         return False
  14.         return True

  15. def find_path(maze,pos):
  16.         mark(maze,pos)
  17.         if end_path(maze):
  18.                 print(pos,end = ' ')
  19.                 return True
  20.         for i in direct:
  21.                 next_pos = (pos[0] + i[0], pos[1] + i[1])
  22.                 if possible(maze,next_pos):
  23.                         if find_path(maze,next_pos):
  24.                                 print(pos,end = ' ')
  25.                                 return True
  26.         return False
  27. #创建一个二维8*8列表,元素为0
  28. def create_maze():
  29.         b = [[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]]
  30.         return b

  31. maze = create_maze()
  32. find_path(maze,(0,0))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-23 16:14:31 | 显示全部楼层
claws0n 发表于 2018-10-23 16:03
可以发代码吗?
图贴旁边的

emmm发了,拜托大神救救菜鸡
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-23 17:00:15 | 显示全部楼层
大腿壮 发表于 2018-10-23 16:14
emmm发了,拜托大神救救菜鸡

可以说没有问题。你的回溯不明显,但还是有就对了。(6,7)在边界了,尝试完全剩下的路径之后,跳出子函数,回到上一层或上几层的函数开始。这是递归头疼的地方。
打印的是 mark() ,只是尝试的路径,不是正确的路径
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-23 21:49:48 | 显示全部楼层
claws0n 发表于 2018-10-23 17:00
可以说没有问题。你的回溯不明显,但还是有就对了。(6,7)在边界了,尝试完全剩下的路径之后,跳出子函数 ...

但是最后打印的时候只有56个坐标值,我画了一下,有好多位置都没有被经过。我不知道为啥会这样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-23 22:11:13 | 显示全部楼层
大腿壮 发表于 2018-10-23 21:49
但是最后打印的时候只有56个坐标值,我画了一下,有好多位置都没有被经过。我不知道为啥会这样

诶,确实漏了,这个很急吗?这几天没空,应该要到礼拜五了,或者看谁路过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-24 08:30:27 | 显示全部楼层
claws0n 发表于 2018-10-23 22:11
诶,确实漏了,这个很急吗?这几天没空,应该要到礼拜五了,或者看谁路过

倒是不急,就是不知道哪里有问题挺烦人的。。。希望能解答一下疑惑,感谢层主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-29 12:30:45 | 显示全部楼层    本楼为最佳答案   
大腿壮 发表于 2018-10-24 08:30
倒是不急,就是不知道哪里有问题挺烦人的。。。希望能解答一下疑惑,感谢层主

变量名与函数小修改。board 去记录走过的路,tour 把坐标记下来。原本的 direct 我换了,不然真的是跑太慢了。主要的架构是 mark, find_path, unmark。其他得看题目的需求。这个大概需要两分钟,没有优化的就是这样。优化的不想搞
  1. def printBoard(board):
  2.     for each in board:
  3.         for i in each:
  4.             print(f'{i:3d}', end = ' ')
  5.         print()

  6. def mark(board, pos, n):
  7.     board[pos[0]][pos[1]] = n

  8. def unmark(board, pos):
  9.     board[pos[0]][pos[1]] = 0

  10. def isPossible(board, x, y, n):
  11.     return 0 <= x < n and 0 <= y < n and board[x][y] ==  0

  12. def knights_tour(board,pos):
  13.     mark(board, pos, 1)
  14.     tour = [pos]
  15.     N = len(board)
  16.     L = N * N
  17.     moves = [(1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1),(-2,1),(-1,2)]
  18.    
  19.     def find_path(board, pos, dep):
  20.         for i in moves:
  21.             next_pos = (pos[0] + i[0], pos[1] + i[1])
  22.             
  23.             if isPossible(board, *next_pos, N):
  24.                 mark(board, next_pos, dep)
  25.                 tour.append(next_pos)
  26.                 if dep == L:
  27.                     return 1
  28.                 if find_path(board, next_pos, dep+1) == 1:
  29.                     return 1
  30.                 else:
  31.                     unmark(board, next_pos)
  32.                     tour.pop()
  33.         return 0

  34.     if find_path(board, pos, 2):
  35.         print("Success!")
  36.         print(tour,'\n')
  37.         printBoard(board)
  38.     else:
  39.         print("Failed!")
  40.     return tour

  41. def create_chessboard(n):
  42.     return [[0]*n for i in range(n)]

  43. board = create_chessboard(8)
  44. knights_tour(board,(0,0))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 17:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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