模拟退火与爬山算法

本文介绍了模拟退火算法与爬山算法的概念和原理。爬山算法通过不断向高处移动寻找局部最优解,但存在缺陷。模拟退火算法通过引入概率机制克服这一缺陷,能在一定程度上找到全局最优解。文章详细解释了模拟退火算法的温度下降过程,并给出了实现技巧和一个实际应用的例题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近学习了一些元启发算法,感觉这些算法的原理都挺有趣的
结合了物理,生物学的现象
(不得不感叹一下前人的脑洞)


爬山算法

先来讲下爬山算法。

考虑这样一个问题:
假设有一个函数 f(x) 如何求它的最大值?
画出它的图像如下:
这里写图片描述
每次在当前位置的两侧判断是否比当前更高
就像爬山一样往高处爬,最终会到达一个较高的位置

但是这通常不是整体最优解,而是局部最优解
像这样:
这里写图片描述
登山者到第一个峰就认为自己登顶了,却没有到达箭头所指的最高点

这就是爬山算法的缺陷

由于爬山算法缺陷巨大,故在一般情况下不使用

何为“退火”?

根据物理学原理,一个高温物体

### 使用模拟退火爬山算法求解4皇后问题 #### 1. 爬山算法实现 爬山算法是一种基于贪婪策略的启发式搜索方法,在每一步都会选择当前状态下的最优解。对于4皇后问题,可以通过定义适应度函数来衡量棋盘上冲突的数量,并通过逐步减少冲突数量找到解决方案。 以下是使用爬山算法解决4皇后问题的具体实现: ```python import random def conflict_count(board): # 计算冲突总数 n = len(board) conflicts = 0 for i in range(n): for j in range(i + 1, n): if board[i] == board[j] or abs(board[i] - board[j]) == j - i: conflicts += 1 return conflicts def generate_neighbor(board): # 生成邻近状态 neighbors = [] n = len(board) for col in range(n): for row in range(n): if board[col] != row: new_board = list(board) new_board[col] = row neighbors.append(new_board) return neighbors def hill_climbing_4_queens(): max_steps = 1000 current = [random.randint(0, 3) for _ in range(4)] steps = 0 while True: neighbor_list = generate_neighbor(current) next_state = min(neighbor_list, key=lambda state: conflict_count(state)) if conflict_count(next_state) >= conflict_count(current): break current = next_state steps += 1 if steps > max_steps: break return current, conflict_count(current) board, conflicts = hill_climbing_4_queens() print(f"Climb Result Board: {board}, Conflicts: {conflicts}") ``` 上述代码实现了基本的爬山算法[^4],其中`conflict_count`用于计算棋盘上的冲突数,而`generate_neighbor`则负责生成所有可能的状态转移。最终返回的是一个满足条件或者接近最优解的棋盘布局以及对应的冲突数目。 --- #### 2. 模拟退火算法实现 模拟退火算法允许接受较差的解以跳出局部最优陷阱,从而更有可能获得全局最优解。其核心在于温度参数和概率接受机制的设计。 下面是针对4皇后问题设计的一个简单版本的模拟退火算法: ```python import math import random def simulated_annealing_4_queens(): initial_temperature = 1000 cooling_rate = 0.99 temperature = initial_temperature current = [random.randint(0, 3) for _ in range(4)] # 初始随机状态 best_solution = list(current) while temperature > 0.001: neighbor = list(generate_random_neighbor(current)) # 随机选取邻居 delta_e = conflict_count(best_solution) - conflict_count(neighbor) if delta_e > 0 or random.uniform(0, 1) < math.exp(delta_e / temperature): current = neighbor if conflict_count(current) < conflict_count(best_solution): best_solution = list(current) if conflict_count(best_solution) == 0: break temperature *= cooling_rate # 温度下降 return best_solution, conflict_count(best_solution) def generate_random_neighbor(board): # 随机改变某个列中的皇后位置 column_to_change = random.randint(0, 3) current_row = board[column_to_change] possible_rows = set(range(4)) - {current_row} new_row = random.choice(list(possible_rows)) new_board = list(board) new_board[column_to_change] = new_row return new_board best_board, final_conflicts = simulated_annealing_4_queens() print(f"Anneal Result Board: {best_board}, Conflicts: {final_conflicts}") ``` 此段代码展示了完整的模拟退火过程[^3],包括初始温度设置、冷却速率调整以及如何利用Metropolis准则决定是否接受新的状态。随着迭代次数增加,系统逐渐趋于稳定并收敛至较优解。 --- #### 总结比较 两种算法各有特点: - **爬山算法**易于理解和实现,但在某些情况下容易陷入局部极值; - **模拟退火算法**虽然复杂度稍高,但由于引入了随机因素,能够有效规避早熟现象,提高寻找全局最优的概率。 两者均适用于小型规模如4皇后这样的场景下快速获取合理解答。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值