遗传算法求解简单背包问题
问题描述:
数据:
weight:
30 40 20 5 15 60 25 10
value:
47 30 9 8 15 66 12 11
代码:
#include <bits/stdc++.h>
using namespace std;
const int item_num = 8; //物品数量
const int weight_max = 100; //最大重量
const int maxn = 5; //种群数量
const double d = 0.1; //常数(用于惩罚)
const double pc = 0.8; //交叉概率
const double pm = 0.3; //变异概率
const int iteration = 300;
typedef struct population
{
int item[item_num];
int value;
int weight;
double fit;
double p;
double q;
}pop;
int wei[item_num] = {30, 40, 20, 5, 15, 60, 25, 10};
int val[item_num] = {47, 30, 9, 8, 15, 66, 12, 11};
int quanju_best_value = 0;
int quanju_best_weight = 0;
int quanju_best_fitness = 0;
int arr[item_num];
int index = 0;
void Init_population(pop p[])
{
for(int i = 0; i < maxn; i++)
{
for(int j = 0; j < item_num; j++)
p[i].item[j] = rand() % 2;
}
}
//适应度函数
void fitness(pop p[])
{
for(int i = 0; i < maxn; i++)
{
int value_sum = 0, weight_sum = 0;
for(int j = 0; j < item_num; j++)
{
if(p[i].item[j] == 1)
{
value_sum += val[j];
weight_sum += wei[j];
}
}
p[i].value = value_sum;
p[i].weight = weight_sum;
if(weight_sum <= weight_max)
{
p[i].fit = value_sum;
}
else //惩罚
{
p[i].fit = value_sum * d;
}
}
}
//选择
void Select(pop p[])
{
double sum_fit = 0;
double sum_q = 0;
for(int i = 0; i < maxn; i++)
sum_fit += p[i].fit;
for(int i = 0; i < maxn; i++)
{
p[i].p = p[i].fit / sum_fit;
sum_q += p[i].p;
p[i].q = sum_q;
}
pop temp[maxn];
for(int i = 0; i < maxn; i++)
{
double a = rand() % 1000 * 0.001;
int j;
if(a <= p[0].q)
{
temp[0] = p[0];
continue;
}
else
{
for(j = 1; j < maxn; j++)
{
if(a > p[j - 1].q && a <= p[j].q)
break;
}
}
temp[i] = p[j];
}
for(int i = 0; i < maxn; i++)
p[i] = temp[i];
}
//交叉
void Crossover(pop p[])
{
int n = (int)(pc * 10);
while(n--)
{
int ia = 0, ib = 0;
while(ia == ib)
{
ia = rand() % maxn;
ib = rand() % maxn;
}
int a = 0, b = 0;
while(a == b || a > b)
{
a = rand() % item_num;
b = rand() % item_num;
}
for(int i = a; i < b; i++)
{
int temp = p[ia].item[i];
p[ia].item[i] = p[ib].item[i];
p[ib].item[i] = temp;
}
}
}
//变异
void Mutation(pop p[])
{
int n = (int)(pm * 10);
while(n--)
{
int index = rand() % maxn;
int a = rand() % item_num;
if(p[index].item[a] == 1)
p[index].item[a] = 0;
else
p[index].item[a] = 1;
}
}
int main()
{
pop p[maxn];
memset(arr, 0, sizeof(arr));
srand((unsigned)time(NULL));
Init_population(p);
int cnt = 0;
while(cnt < iteration)
{
fitness(p);
int jubu_best_value = 0;
int jubu_best_weight = 0;
int jubu_best_index = 0;
double jubu_best_fitness = 0;
for(int i = 0; i < maxn; i++)
if(p[i].fit > jubu_best_fitness)
{
jubu_best_fitness = p[i].fit;
jubu_best_value = p[i].value;
jubu_best_weight = p[i].weight;
jubu_best_index = i;
}
cout<<"第"<<cnt + 1<<"代, 最优解为:"<<endl;
cout<<"价值:"<<jubu_best_value<<",重量:"<<jubu_best_weight<<endl;
cout<<"方案:";
for(int i = 0; i < item_num; i++)
if(p[jubu_best_index].item[i] == 1)
{
cout<<i + 1<<" ";
}
if(jubu_best_fitness > quanju_best_fitness)
{
index = cnt + 1;
quanju_best_fitness = jubu_best_fitness;
quanju_best_value = jubu_best_value;
quanju_best_weight = jubu_best_weight;
for(int i = 0; i < item_num; i++)
arr[i] = p[jubu_best_index].item[i];
}
cout<<endl;
Select(p);
Crossover(p);
Mutation(p);
cnt++;
}
cout<<"全局最优解为:"<<endl;
cout<<"价值:"<<quanju_best_value<<",重量:"<<quanju_best_weight<<endl;
cout<<"方案:";
for(int i = 0; i < item_num; i++)
if(arr[i] == 1)
cout<<i + 1<<" ";
cout<<endl;
cout<<"最优解在第"<<index<<"代产生"<<endl;
}
运行结果: