#include<iostream.h>
#include<stdlib.h>
#include <fstream.h>
#include<time.h>
#include<math.h>
typedef struct
{
int weight;
int value;
}item;
double Random()
{
return (double)rand()/RAND_MAX;
}
int Randomi(int i,int j)
{
return i+rand()%(j-i+1);
}
int GetCi(int *current,int n,item *collection)//计算当前物品列表总价值
{
int result=0;
int i;
for(i=0;i<n;i++)
result+=collection[current[i]-1].value;
return result;
}
int GetAi(int *current,int n,item *collection)//计算当前物品列表总重量
{
int result=0;
int i;
for(i=0;i<n;i++)
result+=collection[current[i]-1].weight;
return result;
}
void ACO_BAG(int B,item *collection,int n,double *info_table)
{
//**************初始化********************************
int i;
int m=n;//蚂蚁个数
double p=0.1;//信息素挥发参数
int **current=new int*[m];//m个蚂蚁装包过程
int *len=new int[m];//m个蚂蚁所装的物品数量
for(i=0;i<m;i++)
len[i]=0;
for(i=0;i<m;i++)
{
current[i]=new int[n];
}
int *elitist=new int[n];//当前最好解
int elitist_len=0;
int V=0;//当前总价值
int Wg=0;//当前总重量
//********************初始化完毕*****************************
//********************主循环***********************************
int s=0;
int cur_len;
int *validnode=new int[n];
double *select=new double[n];//轮盘赌所用
int LT;//轮盘赌所用
double sum;//轮盘赌所用
double x;//轮盘赌所用
int temp;
int rec;
bool flag;
int t,j,k;
while(s<20)//最优解连续20次不变
{
for(i=0;i<m;i++)
{
cur_len=0;
do
{
//找到目前还没装包的物品
LT=0;
for(k=0;k<n;k++)
{
flag=false;
for(t=0;t<cur_len;t++)
{
if(current[i][t]==k+1)
{
flag=true;
break;
}
}
if(flag==false)
{
validnode[LT]=k+1;
LT++;
}
}
//得到目前还没装包的物品的轮盘赌概率
sum=0;
for(k=0;k<LT;k++)
sum+=info_table[validnode[k]-1];
for(k=0;k<LT;k++)
select[k]=info_table[validnode[k]-1]/sum;
for(k=1;k<LT;k++)
select[k]=select[k]+select[k-1];
//选择一个物品装入
x=Random();
if(x<=select[0])
{
current[i][cur_len]=validnode[0];
cur_len++;
}
else
{
for(k=0;k<LT-1;k++)
{
if(x>select[k]&&x<=select[k+1])
{
current[i][cur_len]=validnode[k+1];
cur_len++;
break;
}
}
}
}while(GetAi(current[i],cur_len,collection)<=B&&cur_len<n);
if(cur_len!=n)
cur_len--;
len[i]=cur_len;
}
//更新信息素表和当前最优解
rec=-1;
for(i=0;i<m;i++)
{
temp=GetCi(current[i],len[i],collection);
if(temp>V)
{
V=temp;
rec=i;
}
}
if(rec!=-1)
{
elitist_len=len[rec];
for(i=0;i<elitist_len;i++)
elitist[i]=current[rec][i];
Wg=GetAi(elitist,elitist_len,collection);
}
for(j=0;j<n;j++)
{
flag=false;
for(i=0;i<elitist_len;i++)
{
if(j==(elitist[i]-1))
{
info_table[j]=(1-p)*info_table[j]+p/elitist_len;
flag=true;
break;
}
}
if(flag==false)
{
info_table[j]=(1-p)*info_table[j];
}
}
//改变终止变量
if(rec==-1)
s++;
else
s=0;
}
//**********************输出************************************
cout<<"蚁群算法得到的最优装包为";
for(i=0;i<elitist_len;i++)
cout<<elitist[i]<<" ";
cout<<endl;
cout<<"总重量为:"<<Wg<<endl;
cout<<"总价值为:"<<V<<endl;
//********************主循环完毕**********************************
for(i=0;i<m;i++)
delete current[i];
delete current;
delete[]elitist;
}
int main()
{
srand(time(0));
int B,n;
ifstream infile;
infile.open("bag.txt");
infile >> n;
infile >> B;
item *collection=new item[n];
for (int i = 0; i <= n; i++ )
{
infile >> collection[i].value;
infile >> collection[i].weight;
}
infile.close();
double *info_table=new double[n];
for(i=0;i<n;i++)
info_table[i]=1.0/n;
ACO_BAG(B,collection,n,info_table);
delete[]collection;
delete[]info_table;
return 0;
}
蚁群算法求解0/1背包,注意学习二维动态数组的初始化方法
原文作者:蚁群算法
原文地址: https://blog.csdn.net/vsooda/article/details/7739114
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/vsooda/article/details/7739114
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。