一、实验目的:
通过本实验,掌握遗传算法在解决线性约束优化问题中的应用,了解算法的
核心思想和实现过程。对遗传算法的实现过程有详细的认识,从种群初始化,到
求个体适应值,再对个体进行选择(选择的过程中用到罚函数值和适应度值进行
比较)交叉和变异,最后迭代求出最优解。
二、实验内容
给定一个 7x7 约束规划问题,将物品由 7 个起始站运到 7 个目的地,已知由
i 站运到 j 地的单位运费是 Cij,ai 表示 i 站的供应量,bj 表示 j 地的需求量,
xij 表示从 i 站到 j 地的运量。(i, j =1,2,…,7)。通过遗传算法求运费最小值。
目标函数为:
i,
j
f(x
ij )
P
罚函数为:
kP
p)
f
t(
T
7
7
ijd
1i
1j
其中,k=1,P=1/14,f 为第 t 代群体的平均适应度,T 为最大运行代数,dij 为
约束违反度。
三、实验环境:
操作系统:Microsoft Windows XP Professional
软件:Microsoft Visual C++ 6.0
四、实验设计原理
1、7x7 算法思想
本实验是利用遗传算法策略,通过初始化一定规模的解。每一个解对应一个
个体,通过适应值分析,通过随机联赛选择方法找出最优解。由随机联赛选择方
法选出适应度较好的个体,再对这些个体进行交叉,随之进行变异。再求适应度,,
求最优解,选择,交叉,变异迭代设定值次数下去求出最优解。
2、算法实现的分析
(1)实验的数据为给定的 7x7 运输规划的约束值,费用。
(2)设置种群的数量为 100,7x7 的解转化为一维数组,数组的大小为 49.。
(3)首先初始化种群为 200 个个体, 种群数组大小为 300.,计算 200 个个
体的适应度值。初始化最优解为在种群数组中第一个个体。从 200 个个体选择
100 个个体,存在种群数组下标为 0--99 中。再对这 100 个个体进行交叉后存到
种群数组 100--199 下标中去。接着,每隔 50 代对下标为 0--199 中的个体进行变
异。循环操作,迭代设定的 60000 次,每 3000 次输出一个结果。
(4)随机联赛选择和算术交叉如下:
随机联赛选择:每次从 200 个个体中随机选择 2 个个体进行适应度的比较,
当 2 个个体都是可行解时,选择适应度小的个体。当 2 个个体不是可行解时,比
价适应度值和罚函数值和的大小,选择小的那个。
算术交叉:由两个个体的线性组合而产生出两个新的个体。为了能够进行线
性组合运算,算术交叉的操作对象一般是由浮点数编码表示的个体。
假设在在两个个体 t
AX , t
BX 之间进行算术交叉,交叉运算后产生出的两个
新个体是:
1t
t
1
X
X
A
B
X
X
t
B
t
A
)(
)(
1
1
X
X
t
A
t
B
3、算法实现的步骤
步骤 1:初始化种群 200 个个体
步骤 2:更新染色体信息(适应度,是否为可行解,惩罚函数值)
步骤 3:找出最优解(通过随机联赛选择策略)
步骤 4:每迭代 3000 次输出进化结果
步骤 5:随机选择 100 个较好解的个体,存放到种群数组中
步骤 6:在上述选择出来的 100 个个体中随机选择两个进行交叉,交叉 50 次,
生成 100 个新的个体,存放到种群数组中
步骤 7:每迭代 50 次对上面种群数组中的 200 个个体进行变异
步骤 8:转到步骤 2 继续循环执行,知道达到设定的迭代次数
五、实验结果及分析
分析:随着迭代次数的增加,求出的值越来越小。程序中设置的迭代次数为 60000 次,能得
出的最优解是 4000 多。程序的不足之处不稳定,离最优解还是有一定的距离,存在很大的
改进空间。
附录:
主函数:
#include"sevenseven.h"
#include
#include
#include
#include
using namespace std;
int main()
{
srand((unsigned)time(0));
int
cost[RowNum][ColNum]={
{0,21,50,62,93,77,1000},
{21,0,17,54,67,1000,48},
{50,17,0,60,98,67,25},
{62,54,60,0,27,1000,38},
{93,67,98,27,0,47,42},
{77,1000,67,1000,47,0,35},
{1000,48,25,38,42,35,0}
// 费用表
};
int limit[RowNum][2]={
{20,27},{20,28},{20,25},{23,20},{26,20},{25,20},{26,20}
};
ExternInfo e;
int i,j,low,high;
for(i=0;i
#include
pre)
//小数点后保留一位小数
#include
using namespace std;
double Population::transfer(double
{
temp=0;
int
temp=(int)(pre*1000);
pre=temp;
pre/=1000;
return pre;
}
void Population::InitialExternInfo(ExternInfo EI)
//初始化种群外部信息
{
e=EI;
}
void Population::InitialPop()
//初始化种群信息
{
int i,j;
p.popsize=PopNum*2;
for(i=0;i}
double Population::GetFitness(int
index)
//返回第 index 号染色体的适应函数函数值
{
double fitness=0.0;
int i;
for(i=0;i
5)
else
return false;
return true;
}
double Population::GetPenalty(int index)
//获得惩罚函数值
{
double penalty=0.0,value[7][2]={0.0};
double avgfit=0.0;
int
penalty=ComputeRestraint(index);
for(i=0;i// 计算平均适应度
avgfit/=p.popsize;
penalty*=avgfit;
avgfit=pow(p.cungeneration *1.0/MG,1.0/14);
penalty*=avgfit;
return penalty;
}
void Population::InitialBestIndiv()
{
p.best=p.chromosome[0];
}
int Population::GetBetterIndiv(int r1,int r2)
//获得适应度较高的个体(随机联赛选择方法)
{
int better=-1;
if(p.chromosome[r1].isavailable==true&&p.chromosome[r2].isavailable==true)
if(p.chromosome[r1].fitness