当前位置:   article > 正文

python爬山算法解决八皇后问题_重启爬山法八皇后问题python

重启爬山法八皇后问题python

问题表述为:在8×8的国际象棋棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法

使用爬山算法解决八皇后问题,思路:

1. 先初始化皇后位置,使得每一行每一列一个有且仅有一个皇后

2. 计算冲突的皇后数量(计做冲突值),比如同一行、同一列、同一斜线的数量

3. 准备移动皇后,但是往哪移动呢?每一行皇后只能在自己所在行移动,所以只有列会改变

    比如把第一行皇后从(0,1)移动到(0,0),那么整个棋局的冲突值会发生改变(假设冲突值变小了6->5),此时记录为(0,0):5

   然后遍历所有空位,记录移动到此空位时所有皇后的对应冲突值

4. 找到棋盘中所有空位的冲突值最小的位置,随机选择一个冲突值最小空位置,移动所在行皇后此位置,然后重复上一步3的动作,重新计算棋盘上所有皇后冲突值和所有空位冲突值,循环动作3,直到所有皇后的冲突值为0,此时已经找到一组正确的8皇后位置

5.到第四步已经完成了爬山算法,但是爬山算法有个缺点,有可能找到局部最优,而不是全局最优

   以本案为例他只找到了一组最佳位置,但事实上有很多组。此时可以随机生成多个初始位置(也就是爬山起点分散多个地方),就可以找到不同的最佳答案了

代码如下:

  1. import random, copy, time
  2. """
  3. 解决8皇后问题
  4. 初始化
  5. 随机生成皇后位置,使其不同列、不同行只有一个
  6. """
  7. def init():
  8. # 随机生成皇后位置,使其不同列、不同行只有一个
  9. status = []
  10. for r in range(8):
  11. while len(status) <= 8:
  12. c = random.randint(0, 7)
  13. if c not in [mm[1] for mm in status]:
  14. status.append((r, c))
  15. break
  16. return status
  17. """
  18. 遍历所有皇后
  19. 计算有冲突的皇后坐标(同一行,同一列,斜边)
  20. 计算整个棋盘冲突的数量
  21. 假设初始化传入皇后位置:
  22. [(0, 3), (1, 6), (2, 7), (3, 0), (4, 2), (5, 1), (6, 4), (7, 5)]
  23. """
  24. def conflict(status):
  25. num = 0 # 存储冲突数量
  26. conflict_chess = []
  27. for pos in status:
  28. for other_pos in status:
  29. if pos == other_pos or pos in conflict_chess:
  30. continue
  31. elif pos[0] == other_pos[0] or pos[1] == other_pos[1] or abs(pos[0] - other_pos[0]) == abs(
  32. pos[1] - other_pos[1]):
  33. num += 1
  34. conflict_chess.append(pos)
  35. return num, conflict_chess
  36. """
  37. 遍历所有空位
  38. 计算当行的皇后移动到此空位时整个棋盘的冲突值
  39. 会得出8*8-8 = 56个冲突值
  40. 也就是56种移动方法
  41. 选择冲突值最小的一种进行移动
  42. """
  43. def move_chess(status):
  44. empty_pos = {} # 用字典保存所有空位冲突值
  45. for r in range(8):
  46. for c in range(8):
  47. if (r, c) not in status:
  48. new_status = copy.deepcopy(status)
  49. new_status[r] = (r, c)
  50. empty_pos[(r, c)] = conflict(new_status)[0]
  51. else:
  52. continue
  53. return empty_pos
  54. """
  55. 循环获取冲突数量
  56. 若数量>1,执行move_chess
  57. 指导冲突数量=0,此时寻找到最佳位置
  58. """
  59. def climbing(status):
  60. # 获取当前皇后位置的冲突值
  61. conflict_num = conflict(status)[0]
  62. # 设置循环次数,避免一直循环,冲突值一直无法降到最低0时,自动跳出循环
  63. # 设置移动皇后500次,如果找不到正确位置就重新初始化皇后位置
  64. loop_cnt = 0
  65. while conflict_num != 0 and loop_cnt < 500:
  66. # 获取所有空位冲突值
  67. empty_pos = move_chess(status)
  68. min_value = min(empty_pos.values())
  69. # 获取最小冲突值对应的key 即坐标pos
  70. min_pos_ls = []
  71. for k, v in empty_pos.items():
  72. # print(v, min_value)
  73. if v == min_value and (k not in min_pos_ls):
  74. min_pos_ls.append(k)
  75. # print(min_pos_ls, min_value)
  76. # print(status)
  77. # 随机取一个空位点,与当前同一行皇后交换位置,然后计算所有空位置的冲突值和当前棋局内皇后自身冲突值
  78. i = random.randint(0, len(min_pos_ls) - 1)
  79. status[min_pos_ls[i][0]] = min_pos_ls[i]
  80. conflict_num = conflict(status)[0]
  81. loop_cnt += 1
  82. return status, loop_cnt
  83. if __name__ == '__main__':
  84. # 这一个随机数会导致一直找不到最高点
  85. # status = [(0, 0), (1, 2), (2, 4), (3, 3), (4, 1), (5, 5), (6, 7), (7, 6)]
  86. # climbing(status)
  87. """
  88. 生成随机位置,迭代600次尽可能多的找出八皇后不同位置
  89. """
  90. start = time.time()
  91. all_pos = []
  92. for i in range(600):
  93. status = init()
  94. # 设置loop_cnt防止一直陷入死循环无法找到最佳点
  95. # 如果一直找不到就跳出来并且重新生成初始位置
  96. status, loop_cnt = climbing(status)
  97. # print(loop_cnt)
  98. if loop_cnt == 500:
  99. continue
  100. elif status not in all_pos:
  101. all_pos.append(status)
  102. end = time.time()
  103. print("一共找到{}组八皇后位置,共耗时{}s".format(len(all_pos), end - start))
  104. for pos in all_pos:
  105. print(pos)

运行结果如下:

  1. C:\Users\LU\.conda\envs\ai_course\python.exe C:/Users/LU/PycharmProjects/ai_course/eight_queens_2d.py
  2. 一共找到92组八皇后位置,共耗时31.383877515792847s
  3. [(0, 5), (1, 3), (2, 1), (3, 7), (4, 4), (5, 6), (6, 0), (7, 2)]
  4. [(0, 1), (1, 4), (2, 6), (3, 0), (4, 2), (5, 7), (6, 5), (7, 3)]
  5. [(0, 5), (1, 2), (2, 0), (3, 6), (4, 4), (5, 7), (6, 1), (7, 3)]
  6. [(0, 6), (1, 3), (2, 1), (3, 7), (4, 5), (5, 0), (6, 2), (7, 4)]
  7. [(0, 4), (1, 2), (2, 0), (3, 5), (4, 7), (5, 1), (6, 3), (7, 6)]
  8. [(0, 4), (1, 2), (2, 0), (3, 6), (4, 1), (5, 7), (6, 5), (7, 3)]
  9. [(0, 3), (1, 7), (2, 0), (3, 4), (4, 6), (5, 1), (6, 5), (7, 2)]
  10. [(0, 3), (1, 6), (2, 0), (3, 7), (4, 4), (5, 1), (6, 5), (7, 2)]
  11. [(0, 4), (1, 6), (2, 0), (3, 2), (4, 7), (5, 5), (6, 3), (7, 1)]
  12. [(0, 5), (1, 1), (2, 6), (3, 0), (4, 3), (5, 7), (6, 4), (7, 2)]
  13. [(0, 3), (1, 1), (2, 7), (3, 5), (4, 0), (5, 2), (6, 4), (7, 6)]
  14. [(0, 5), (1, 7), (2, 1), (3, 3), (4, 0), (5, 6), (6, 4), (7, 2)]
  15. [(0, 2), (1, 5), (2, 1), (3, 6), (4, 0), (5, 3), (6, 7), (7, 4)]
  16. [(0, 3), (1, 6), (2, 4), (3, 2), (4, 0), (5, 5), (6, 7), (7, 1)]
  17. [(0, 4), (1, 1), (2, 3), (3, 5), (4, 7), (5, 2), (6, 0), (7, 6)]
  18. [(0, 1), (1, 3), (2, 5), (3, 7), (4, 2), (5, 0), (6, 6), (7, 4)]
  19. [(0, 4), (1, 2), (2, 7), (3, 3), (4, 6), (5, 0), (6, 5), (7, 1)]
  20. [(0, 3), (1, 5), (2, 7), (3, 1), (4, 6), (5, 0), (6, 2), (7, 4)]
  21. [(0, 4), (1, 1), (2, 7), (3, 0), (4, 3), (5, 6), (6, 2), (7, 5)]
  22. [(0, 5), (1, 2), (2, 6), (3, 1), (4, 3), (5, 7), (6, 0), (7, 4)]
  23. [(0, 0), (1, 6), (2, 3), (3, 5), (4, 7), (5, 1), (6, 4), (7, 2)]
  24. [(0, 5), (1, 3), (2, 0), (3, 4), (4, 7), (5, 1), (6, 6), (7, 2)]
  25. [(0, 2), (1, 5), (2, 1), (3, 4), (4, 7), (5, 0), (6, 6), (7, 3)]
  26. [(0, 2), (1, 5), (2, 7), (3, 1), (4, 3), (5, 0), (6, 6), (7, 4)]
  27. [(0, 4), (1, 6), (2, 1), (3, 3), (4, 7), (5, 0), (6, 2), (7, 5)]
  28. [(0, 3), (1, 0), (2, 4), (3, 7), (4, 1), (5, 6), (6, 2), (7, 5)]
  29. [(0, 6), (1, 1), (2, 5), (3, 2), (4, 0), (5, 3), (6, 7), (7, 4)]
  30. [(0, 6), (1, 1), (2, 3), (3, 0), (4, 7), (5, 4), (6, 2), (7, 5)]
  31. [(0, 2), (1, 7), (2, 3), (3, 6), (4, 0), (5, 5), (6, 1), (7, 4)]
  32. [(0, 3), (1, 5), (2, 7), (3, 2), (4, 0), (5, 6), (6, 4), (7, 1)]
  33. [(0, 2), (1, 4), (2, 6), (3, 0), (4, 3), (5, 1), (6, 7), (7, 5)]
  34. [(0, 2), (1, 4), (2, 1), (3, 7), (4, 0), (5, 6), (6, 3), (7, 5)]
  35. [(0, 4), (1, 1), (2, 5), (3, 0), (4, 6), (5, 3), (6, 7), (7, 2)]
  36. [(0, 6), (1, 0), (2, 2), (3, 7), (4, 5), (5, 3), (6, 1), (7, 4)]
  37. [(0, 2), (1, 5), (2, 7), (3, 0), (4, 4), (5, 6), (6, 1), (7, 3)]
  38. [(0, 4), (1, 7), (2, 3), (3, 0), (4, 2), (5, 5), (6, 1), (7, 6)]
  39. [(0, 2), (1, 0), (2, 6), (3, 4), (4, 7), (5, 1), (6, 3), (7, 5)]
  40. [(0, 5), (1, 2), (2, 6), (3, 3), (4, 0), (5, 7), (6, 1), (7, 4)]
  41. [(0, 4), (1, 7), (2, 3), (3, 0), (4, 6), (5, 1), (6, 5), (7, 2)]
  42. [(0, 5), (1, 3), (2, 6), (3, 0), (4, 7), (5, 1), (6, 4), (7, 2)]
  43. [(0, 3), (1, 1), (2, 4), (3, 7), (4, 5), (5, 0), (6, 2), (7, 6)]
  44. [(0, 5), (1, 2), (2, 6), (3, 1), (4, 7), (5, 4), (6, 0), (7, 3)]
  45. [(0, 5), (1, 3), (2, 6), (3, 0), (4, 2), (5, 4), (6, 1), (7, 7)]
  46. [(0, 3), (1, 6), (2, 4), (3, 1), (4, 5), (5, 0), (6, 2), (7, 7)]
  47. [(0, 2), (1, 5), (2, 1), (3, 6), (4, 4), (5, 0), (6, 7), (7, 3)]
  48. [(0, 6), (1, 4), (2, 2), (3, 0), (4, 5), (5, 7), (6, 1), (7, 3)]
  49. [(0, 1), (1, 6), (2, 4), (3, 7), (4, 0), (5, 3), (6, 5), (7, 2)]
  50. [(0, 5), (1, 0), (2, 4), (3, 1), (4, 7), (5, 2), (6, 6), (7, 3)]
  51. [(0, 5), (1, 2), (2, 4), (3, 6), (4, 0), (5, 3), (6, 1), (7, 7)]
  52. [(0, 5), (1, 2), (2, 0), (3, 7), (4, 4), (5, 1), (6, 3), (7, 6)]
  53. [(0, 2), (1, 5), (2, 3), (3, 0), (4, 7), (5, 4), (6, 6), (7, 1)]
  54. [(0, 2), (1, 5), (2, 3), (3, 1), (4, 7), (5, 4), (6, 6), (7, 0)]
  55. [(0, 1), (1, 5), (2, 7), (3, 2), (4, 0), (5, 3), (6, 6), (7, 4)]
  56. [(0, 2), (1, 6), (2, 1), (3, 7), (4, 4), (5, 0), (6, 3), (7, 5)]
  57. [(0, 4), (1, 6), (2, 3), (3, 0), (4, 2), (5, 7), (6, 5), (7, 1)]
  58. [(0, 5), (1, 2), (2, 4), (3, 7), (4, 0), (5, 3), (6, 1), (7, 6)]
  59. [(0, 5), (1, 2), (2, 0), (3, 7), (4, 3), (5, 1), (6, 6), (7, 4)]
  60. [(0, 2), (1, 5), (2, 7), (3, 0), (4, 3), (5, 6), (6, 4), (7, 1)]
  61. [(0, 1), (1, 7), (2, 5), (3, 0), (4, 2), (5, 4), (6, 6), (7, 3)]
  62. [(0, 3), (1, 5), (2, 0), (3, 4), (4, 1), (5, 7), (6, 2), (7, 6)]
  63. [(0, 1), (1, 5), (2, 0), (3, 6), (4, 3), (5, 7), (6, 2), (7, 4)]
  64. [(0, 6), (1, 2), (2, 7), (3, 1), (4, 4), (5, 0), (6, 5), (7, 3)]
  65. [(0, 0), (1, 4), (2, 7), (3, 5), (4, 2), (5, 6), (6, 1), (7, 3)]
  66. [(0, 3), (1, 7), (2, 4), (3, 2), (4, 0), (5, 6), (6, 1), (7, 5)]
  67. [(0, 3), (1, 1), (2, 6), (3, 2), (4, 5), (5, 7), (6, 0), (7, 4)]
  68. [(0, 3), (1, 6), (2, 2), (3, 7), (4, 1), (5, 4), (6, 0), (7, 5)]
  69. [(0, 4), (1, 0), (2, 3), (3, 5), (4, 7), (5, 1), (6, 6), (7, 2)]
  70. [(0, 4), (1, 0), (2, 7), (3, 5), (4, 2), (5, 6), (6, 1), (7, 3)]
  71. [(0, 5), (1, 1), (2, 6), (3, 0), (4, 2), (5, 4), (6, 7), (7, 3)]
  72. [(0, 6), (1, 3), (2, 1), (3, 4), (4, 7), (5, 0), (6, 2), (7, 5)]
  73. [(0, 4), (1, 1), (2, 3), (3, 6), (4, 2), (5, 7), (6, 5), (7, 0)]
  74. [(0, 3), (1, 7), (2, 0), (3, 2), (4, 5), (5, 1), (6, 6), (7, 4)]
  75. [(0, 4), (1, 0), (2, 7), (3, 3), (4, 1), (5, 6), (6, 2), (7, 5)]
  76. [(0, 3), (1, 1), (2, 6), (3, 4), (4, 0), (5, 7), (6, 5), (7, 2)]
  77. [(0, 2), (1, 4), (2, 1), (3, 7), (4, 5), (5, 3), (6, 6), (7, 0)]
  78. [(0, 2), (1, 6), (2, 1), (3, 7), (4, 5), (5, 3), (6, 0), (7, 4)]
  79. [(0, 1), (1, 4), (2, 6), (3, 3), (4, 0), (5, 7), (6, 5), (7, 2)]
  80. [(0, 0), (1, 5), (2, 7), (3, 2), (4, 6), (5, 3), (6, 1), (7, 4)]
  81. [(0, 3), (1, 1), (2, 7), (3, 4), (4, 6), (5, 0), (6, 2), (7, 5)]
  82. [(0, 4), (1, 6), (2, 1), (3, 5), (4, 2), (5, 0), (6, 7), (7, 3)]
  83. [(0, 3), (1, 0), (2, 4), (3, 7), (4, 5), (5, 2), (6, 6), (7, 1)]
  84. [(0, 6), (1, 2), (2, 0), (3, 5), (4, 7), (5, 4), (6, 1), (7, 3)]
  85. [(0, 4), (1, 6), (2, 0), (3, 3), (4, 1), (5, 7), (6, 5), (7, 2)]
  86. [(0, 0), (1, 6), (2, 4), (3, 7), (4, 1), (5, 3), (6, 5), (7, 2)]
  87. [(0, 2), (1, 4), (2, 7), (3, 3), (4, 0), (5, 6), (6, 1), (7, 5)]
  88. [(0, 7), (1, 1), (2, 3), (3, 0), (4, 6), (5, 4), (6, 2), (7, 5)]
  89. [(0, 7), (1, 3), (2, 0), (3, 2), (4, 5), (5, 1), (6, 6), (7, 4)]
  90. [(0, 7), (1, 1), (2, 4), (3, 2), (4, 0), (5, 6), (6, 3), (7, 5)]
  91. [(0, 1), (1, 6), (2, 2), (3, 5), (4, 7), (5, 4), (6, 0), (7, 3)]
  92. [(0, 4), (1, 6), (2, 1), (3, 5), (4, 2), (5, 0), (6, 3), (7, 7)]
  93. [(0, 3), (1, 1), (2, 6), (3, 2), (4, 5), (5, 7), (6, 4), (7, 0)]
  94. [(0, 7), (1, 2), (2, 0), (3, 5), (4, 1), (5, 4), (6, 6), (7, 3)]
  95. Process finished with exit code 0

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/710730
推荐阅读
相关标签
  

闽ICP备14008679号