[01背包] 遗传算法

{

最近向 我不容易 学习了遗传算法

他是专门研究这智能搜索这一方面的 水平很高

在我用ID算法解决"十滴水"小游戏时

他用遗传算法也写了 很强大

我用从他那所学的遗传算法 写了一个01背包问题的程序

}

 

01背包问题 大家应该很熟悉

是背包问题的一种

不过值得注意的是

背包问题是NPH问题

(如果容量和体积是整数且有范围的话 自然用DP可以很好的解决)

对于此类没有多项式复杂度算法的问题

我们一般用搜索解决

对于01背包问题

最为朴素的做法是 枚举每个物品取还是不取 再选取最优解

不过这样的复杂度是2^n 加了可行性和最优性剪枝也不能优化太多

这是我们就会考虑智能搜索算法

此类算法很强大 目前我只了解过遗传算法- -|||

于是我就用遗传算法写了一个

在理解 我不容易 的教导的基础之上 我还参考了这篇论文

http://www.docin.com/p-47510663.html

 

遗传算法本质是模拟达尔文的生物进化论思想

将一个解视为一个生物 通过对这样的生物的种群进行繁衍

不断地使生物得到进化 也就是让解得到不断的优化

根据生物学理论 生物的性状由基因控制

我们仅保存DNA即遗传信息进行模拟

并且还设计一个函数来根据遗传信息估计生物的适应度

适应度帮助我们得到生物生存和繁衍的概率

而且 由于性状之间不互相干扰

所以遗传算法多用于解决组合类的最优化问题

01背包 每个物品取与不取与其他物品的情况无关

所以可以用遗传算法解决

我们把繁衍的过程 简化为以下几个步骤

选择 交叉 变异

基于贪心思想 又附加了修复 修正的操作

具体内容上述论文讲的很清楚

我讲一下几个注意点 方便程序实现

  *实数运算有精度问题 需要多加注意

  *建议将各操作分为各个函数写

  高度面向过程的程序对与遗传算法这种多块的代码由为重要

    主要表现在 变量不会搞混 查错方便

  *几个基本变量千万不要搞错 最大繁衍代数 种群规模 遗传信息规模

排序可以用nlogn级别的 数据大了优化比较明显

另外 几个参数是需要根据测试来定

比如 变异概率 最大繁衍代数 种群规模

可以同过测试来不断微调 直至达到满意的效果

 

最后给出我的代码

自以为写的比较优美 不过也变的很长

 

1 {$I+,Q+,R+,S+}
2  const maxn=200; maxp=20; maxt=500;
3 xrr=2; dsn=2;
4 pm=0.1;
5  var p,tempp:array[1..maxp,1..maxn]of longint;
6 ans:array[1..maxn]of longint;
7 c,w,v:array[1..maxn]of real;
8 h:array[1..maxp]of real;
9 n,m,i,j:longint;
10 max:real;
11  procedure revise(x:longint; y:real);
12  var i,j,t,z:longint;
13 temp:array[1..maxn]of longint;
14  begin
15 t:=0;
16  for i:=1 to n do
17 if p[x][i]=0
18 then begin
19 inc(t);
20 temp[t]:=i;
21 end;
22 for i:=1 to t-1 do
23 for j:=i+1 to t do
24 if c[temp[i]]<c[temp[j]]
25 then begin
26 z:=temp[i];
27 temp[i]:=temp[j];
28 temp[j]:=z;
29 end;
30 i:=0;
31 while (i<t)and(y<m) do
32 begin
33 inc(i);
34 p[x][temp[i]]:=1;
35 y:=y+w[temp[i]];
36 end;
37 if y>m then p[x][temp[i]]:=0;
38 end;
39 procedure repair(x:longint; y:real);
40 var i,j,t,z:longint;
41 temp:array[1..maxn]of longint;
42 begin
43 t:=0;
44 for i:=1 to n do
45 if p[x][i]=1
46 then begin
47 inc(t);
48 temp[t]:=i;
49 end;
50 for i:=1 to t-1 do
51 for j:=i+1 to t do
52 if c[temp[i]]>c[temp[j]]
53 then begin
54 z:=temp[i];
55 temp[i]:=temp[j];
56 temp[j]:=z;
57 end;
58 i:=0;
59 while (i<n)and(y>m) do
60 begin
61 inc(i);
62 p[x][temp[i]]:=0;
63 y:=y-w[temp[i]];
64 end;
65 end;
66 procedure create;
67 var i,j:longint;
68 t:real;
69 begin
70 for i:=1 to maxp do
71 begin
72 t:=0;
73 for j:=1 to n do
74 begin
75 p[i][j]:=random(2);
76 t:=t+w[j]*p[i][j];
77 end;
78 if t<m then revise(i,t);
79 if t>m then repair(i,t);
80 end;
81 end;
82 procedure propagate;
83 var i,j,x,y,t:longint;
84 k,s,tr,tr0,r:real;
85 f,temp:array[1..maxn]of longint;
86 begin
87 for i:=1 to maxp do h[i]:=0;
88 for i:=1 to maxp do
89 for j:=1 to n do
90 h[i]:=h[i]+v[j]*p[i][j];
91 for i:=1 to maxp-1 do
92 for j:=i+1 to maxp do
93 if h[i]<h[j]
94 then begin
95 move(p[i],temp,sizeof(p[i]));
96 move(p[j],p[i],sizeof(p[j]));
97 move(temp,p[i],sizeof(temp));
98 k:=h[i]; h[i]:=h[j]; h[j]:=k;
99 end;
100 for i:=1 to maxp do f[i]:=0;
101 for i:=1 to dsn do f[i]:=1;
102 s:=0;
103 for i:=1 to maxp do s:=s+h[i];
104 for i:=1 to maxp do h[i]:=h[i]/s;
105 i:=dsn;
106 tr0:=0;
107 for i:=1 to dsn do tr0:=tr0+h[i];
108 while i<maxp-xrr do
109 begin
110 j:=dsn;
111 tr:=tr0; r:=random;
112 while tr<r do
113 begin
114 inc(j);
115 tr:=tr+h[j];
116 end;
117 if f[j]=1 then continue;
118 f[j]:=1;
119 inc(i);
120 end;
121 for i:=1 to maxp do
122 if f[i]=0
123 then begin
124 s:=0;
125 for j:=1 to n do
126 begin
127 p[i][j]:=random(2);
128 s:=s+w[j]*p[i][j];
129 end;
130 if s<m then revise(i,s);
131 if s>m then repair(i,s);
132 end;
133 t:=dsn;
134 while t<maxp do
135 begin
136 x:=0;
137 tr:=0; r:=random;
138 while tr<r do
139 begin
140 inc(x);
141 tr:=tr+h[x];
142 end;
143 y:=0;
144 tr:=0; r:=random;
145 while tr<r do
146 begin
147 inc(y);
148 tr:=tr+h[y];
149 end;
150 inc(t);
151 for i:=1 to n do
152 if random(2)=1
153 then tempp[t][i]:=p[x][i]
154 else tempp[t][i]:=p[y][i];
155 if random<pm
156 then for i:=1 to n do
157 tempp[t][i]:=random(2);
158 s:=0;
159 for i:=1 to n do
160 s:=s+w[i]*tempp[t][i];
161 move(tempp[t],p[t],sizeof(tempp[t]));
162 if s<m then revise(t,s);
163 if s>m then repair(t,s);
164 s:=0;
165 for i:=1 to n do s:=s+v[i]*p[t][i];
166 if s>max
167 then begin
168 max:=s;
169 move(p[t],ans,sizeof(p[t]));
170 end;
171 end;
172 end;
173 begin
174 randomize;
175 assign(input,'01.in'); reset(input);
176 assign(output,'01.out'); rewrite(output);
177 readln(n,m);
178 for i:=1 to n do
179 begin
180 read(w[i]); read(v[i]);
181 c[i]:=v[i]/w[i];
182 end;
183 create;
184 max:=0;
185 for i:=1 to maxt do
186 propagate;
187 writeln(max:0:4);
188 for i:=1 to n do
189 write(ans[i]);
190 writeln;
191 close(input); close(output);
192 end.
193

 

遗传算法 是生物学与算法的强大结合!

 

Bob Han 原创 转载请注明出处

posted on 2010-09-30 19:25  Master_Chivu  阅读(4982)  评论(7编辑  收藏  举报

导航