写在前面:要打数学建模,学点好玩的

模拟退火

是一个随机化算法

借鉴固体的退火过程

最核心的地方在于,对前一状态进行随机扰动,如果更优就作为当前状态,如果不优,有一定概率取为当前状态

局部最优的地方不一定全局最优,所以有一定概率从局部最优跳出,去寻找全局最优

参数有:

T_begin : 初始温度

T_end : 结束温度

: 退火速率系数

T : 当前温度

以上是控制随机化过程中对状态的遍历程度完全/不完全,具体来说,每得到一个随机答案,当前温度都会乘 ,直到低于结束温度

在随机扰动时,会有 L : 马尔科夫链长度

在取答案(以越小越优为例)时,设第 个状态的答案 ,定义 如下: 之间随机取一个 , 若 ,第 个状态将被接受

解决 背包问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
% 模拟退火
clear;
clc;
close all;
N=input('有多少物品:');
W=input('背包承重:');
w=input('依次输入物品重量:');
v=input('依次输入物品价值:');
% init

alpha=0.95;
t_begin=200;
t_end=0.1;
t=t_begin;
solution_new=ones(1,length(w));
solution_current=zeros(1,length(w));
value_current=0;
value_best=0;
solution_best=solution_current;
counter=0;

while(t>t_end)

counter=counter+1;

for i = 1:100

index=randi([1,length(w)],1,1);
solution_new(1,index)=~solution_new(1,index);

solution_new.*w; % 每个位置相乘

while sum(solution_new.*w)>W
index=randi([1,length(w)],1,1);
solution_new(1,index)=~solution_new(1,index);
end

value_new=sum(solution_new.*v);

possibility=exp((value_new-value_current)/t);
if possibility>rand
value_current=value_new;
solution_current=solution_new;
else
solution_new=solution_current;
end

if value_current>value_best
value_best=value_current;
solution_best=solution_current;
end

end

value_list(counter,:)=value_best;
solution_list(counter,:)=solution_best;
t=t*alpha;
end

figure(3);
plot(value_list);
xlabel('迭代次数');
ylabel('目标函数值');
title('适应度进化曲线');
fprintf('最大价值:%f,货物重量%d\n',value_best,sum(solution_best.*w));
disp(['解:',num2str(solution_best)]);

遗传算法

神经网络

本文采用CC-BY-SA-3.0协议,转载请注明出处
作者: wsy_jim