当前位置:   article > 正文

高级搜索之爬山法(Hill Climbing)_hillclimbing算法

hillclimbing算法

一、通俗理解

        爬山的目标是朝最高的方向移动,而当爬山者位于分岔路口的时候,介于视野受限无法知道哪条路才是通往最高峰,但是我们可以判断每条路的陡峭程度来选择路径,即保证至少这一段路是爬得最高的,爬山者会遵循这个原则一直爬,直到一个山峰即没有往上只有往下的路停止

二、性质

  • 局限性:采用贪婪局部搜索,每次都选择当前邻近状态中能够最大化目标函数值的状态,而不考虑长远的影响
  • 空间复杂度小:只需记录当前状态和其每个后继状态的目标函数值
  • 时间复杂度相对小:在很大的状态空间内能很快朝着解的方向进展

三、不具有完备性的原因

  • 山肩:比它相邻的每个地方都高,但是比最高峰要低-->爬山法陷入局部最优解
  • 山脊:一连串的局部最优值-->爬山法陷入死循环
  • 平原:领域的目标函数值几乎一样-->爬山法效率很低或直接失效

四、算法流程

        比较简单, 每一次都从当前解的领域解中找到目标函数值最大的解作为候选解更新,一旦找到最优解则退出,或者到达最大迭代次数也退出

五、八皇后问题

描述:将8个皇后放置在一个8×8的棋盘上,使得不存在两个皇后位于同行、同列和同对角线

  1. import random
  2. #随机生成一个棋盘
  3. def initial_state(board_size):
  4. state = random.sample(range(board_size),board_size)
  5. return state
  6. #统计冲突函数:输入皇后位置列表,返回当前位置下的冲突数量
  7. def count_conflicts(state):
  8. conflicts = 0
  9. size = len(state)
  10. for i in range(0,size-1):
  11. for j in range(i+1,size):
  12. diag1 = (state[i] - i) == (state[j] - j)
  13. diag2 = (state[i] + i) == (state[j] + j)
  14. if state[i] == state[j] or diag1 or diag2:
  15. conflicts += 1
  16. return conflicts
  17. #皇后位置改变函数:输入新位置,返回新列表
  18. def move_queen(new_col,row,state):
  19. new_state = list(state)
  20. new_state[row] = new_col
  21. return new_state
  22. #爬山法
  23. def climb_hills(cur_state,max_iterations=1000):
  24. iterations = 0
  25. size = len(cur_state)
  26. cur_conflicts = count_conflicts(cur_state)
  27. # 不断更新当前状态为后继最佳状态,直到冲突数为0或到达最大迭代数
  28. while cur_conflicts != 0 and iterations < max_iterations:
  29. # 以行序为主序即从上往下遍历,将每行的皇后的当前列改变为最佳列
  30. for row in range(size):
  31. cur_col = cur_state[row]
  32. best_col = cur_state[row]
  33. best_conflicts = cur_conflicts
  34. # 找到当前行的最佳列
  35. for new_col in range(size):
  36. if new_col != cur_col:
  37. #横移皇后得到的新状态和新冲突数
  38. new_state = move_queen(new_col,row,cur_state)
  39. new_conflicts = count_conflicts(new_state)
  40. #当且仅当新冲突数<旧冲突数时,才更新
  41. if new_conflicts < best_conflicts:
  42. best_col = new_col
  43. best_conflicts = new_conflicts
  44. cur_state[row] = best_col
  45. cur_conflicts = best_conflicts
  46. iterations += 1
  47. return cur_state
  48. state = initial_state(8)
  49. print('起始棋盘:', state)
  50. result = climb_hills(state)
  51. if count_conflicts(result) == 0:
  52. print('成功:', result)
  53. else:
  54. print('失败:', result)

六、评测

  1. 从一个随机生成的八皇后问题的状态开始,最陡上升的爬山法86%的情况下会被卡住,只有14%的问题实例能求解。
  2. 这个算法速度很快,成功找到最优解的平均步数是4步,被卡住的平均步数是3步,但这对于包含88=16,777,216个状态的状态空间已经是不错的结果
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/710732
推荐阅读
相关标签
  

闽ICP备14008679号