现在的位置: 首页 > 综合 > 正文

蚁群算法求解0/1背包,注意学习二维动态数组的初始化方法

2013年10月13日 ⁄ 综合 ⁄ 共 2937字 ⁄ 字号 评论关闭
#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;
}

抱歉!评论已关闭.