蚁群算法求解0/1背包,注意学习二维动态数组的初始化方法
2012-07-12 10:10
555 查看
#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 ; } int *elitist=new int ;//当前最好解 int elitist_len=0; int V=0;//当前总价值 int Wg=0;//当前总重量 //********************初始化完毕***************************** //********************主循环*********************************** int s=0; int cur_len; int *validnode=new int ; double *select=new double ;//轮盘赌所用 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 ; for (int i = 0; i <= n; i++ ) { infile >> collection[i].value; infile >> collection[i].weight; } infile.close(); double *info_table=new double ; 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; }
相关文章推荐
- 学习二维动态数组指针做矩阵运算的方法
- 数组(一维、二维、三维)的动态申请及用vector的表示方法
- C语言学习8:malloc返回的void*类型指针不可以做更改,free双重释放,二维数组的初始化和打印,a和a[0]和a[0][0]的区别,数组指针(*p)[3],指针数组*a[10],动态内存分配版约瑟夫环,动态分配版去空格和逗号处理,二级指针与二维数组互用
- C二维动态读取长度的数组初始化
- c++ 二维动态数组初始化及作为参数传递
- 数组(一维、二维、三维)的动态申请及用vector的表示方法
- C++ 与“类”有关的注意事项总结(十):类对象数组初始化(三种方法)
- 关于vector二维动态数组初始化
- 数组(一维、二维、三维)的动态申请及用vector 的表示方法
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
- 数组(一维、二维、三维)的动态申请及用vector的表示方法
- 用vector<CStringArray>会报错;数组(一维、二维、三维)的动态申请及用vector的表示方法
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
- js之二维数组定义和初始化三种方法
- 数组(一维、二维、三维)的动态申请及用vector的表示方法
- C/C++ 二维数据 静态动态声明和初始化及访问方法实例
- 《C++笔记》 Part8 一维、二维、三维数组的动态申请及用vector的表示方法
- java学习(2)数组详解(包括数据的初始化、比较、排序、重要方法)
- delphi 初始化多维动态数组的方法
- C/C++ 二维数据 静态动态声明和初始化及访问方法实例