c语言贪婪遗传算法算法背包问题,求高手帮我用C语言写一个运用贪心和遗传算法求解背包问题的程序。。。。谢谢!!!!!!十分紧急!!!...

本文探讨了如何将传统的动态规划算法与遗传算法结合,解决背包问题中的物品选择问题。通过实例数据展示,展示了改进后的算法在背包容量受限下,如何找到总价值最大且重量最接近的物品组合,最终达到3103的总价值,且总重量为1000。重点介绍了算法流程、性能对比以及优化结果。
摘要由CSDN通过智能技术生成

匿名用户

1级

2013-07-13 回答

1、程序开发环境

开发环境:Visual C++6.0 (把Fortran程序改为VC)

操作系统:Windows 2003 Professional

2、程序性能对比

运行时间与加速比(如表1所示)

进程数p(个) 1 2 4

运行时间t(秒) 129s 78s 38s

加速比s  1.65 3.38

表1、运行时间与加速比

3、程序运行结果:

实例数据:

假设物体的重量Weight、物体的收益Profit和背包的容量Contain 分别为:

Weight={ 80,82,85,70,72,    70,66,50,55,25 ,

50,55,40,48,50,     32,22,60,30,32 ,

40,38,35,32,25,     28,30,22,50,30 ,

45,30,60,50,20 ,    65,20,25,30,10 ,

20,25,15,10,10 ,    10,4, 4, 2, 1   }

Profit={  220,208,198,192,180,    180,165,162,160,158,

155,130,125,122,120 ,   118,115,110,105,101,

100,100,98, 96, 95,     90, 88, 82, 80, 77 ,

75, 73, 72, 70, 69,     66, 65, 63, 60, 58,

56, 50, 30, 20, 15,      10, 8,  5,  3,  1}

Contain=1000,

如何选择哪些物品装入该背包可使得在背包的容量约束限制之内所装物品的总价值最大?

传统的算法(动态规划、递归回溯法和贪心算法所得结果:

总价值为3077 , 总重量为999。

2001年张铃,张钹教授在计算机学报上发表的《佳点集遗传算法》所得结果

总价值为3103, 总重量为1000。

我们算法所得结果:                   总价值为3103, 总重量为1000。

我们所求得最优解的个体分配情况为:

11010   10111   10110   11011   01111   11101   00001   01001   10000

01000

算法 最大迭代次数 总价值为 总重量为

传统的算法 400 3077 999

佳点集算法 70 3103 1000

遗传算法    75 3103 1000

// knapsack.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include 

#include 

#include 

#include 

#include 

#include 

// 重要常量参数

#define popsize 200   //种群的规模

#define pc 0.618        //杂交概率

#define pm 0.03        //变异概率

#define lchrom 50      //染色体长度

#define maxgen 1000     //最大进化代数

struct population

{

unsigned int chrom[lchrom];   //染色体

double weight;                //背包重量

double fitness;               //适应度

unsigned int parent1,parent2,cross;  //双亲、交叉点

};

//新生代种群、父代种群

struct population oldpop[popsize],newpop[popsize];

//背包问题中物体重量、收益、背包容量

int weight[lchrom],profit[lchrom],contain;

//种群的总适应度、最小、最大、平均适应度

double sumfitness,minfitness,maxfitness,avgfitness;

//计算适应度时使用的 惩罚函数系数

double alpha;

//一个种群中最大和最小适应度的个体

int    minpop,maxpop;

/* 读入背包信息,并且计算惩罚函数系数 */

void read_infor()

{

FILE *fp;

int j;

//获取背包问题信息文件

if ((fp=fopen("knapsack.txt","r"))==NULL)

{

//读取文件失败

AfxMessageBox("The file is not found",MB_OK,NULL);

return;

}

//读入物体收益信息

for (j=0;j

{

fscanf(fp,"%d",&profit[j]);

}

//读入物体重量信息

for (j=0;j

{

fscanf(fp,"%d",&weight[j]);

}

//读入背包容量

fscanf(fp,"%d",&contain);

fclose(fp);

}

//根据计算的个体重量,判断此个体是否该留在群体中

double cal_weight(unsigned int *chr)

{

int j;

double pop_weight;//背包重量

pop_weight=0;

for (j=0;j

{

pop_weight=pop_weight+(*chr)*weight[j];

chr++;

}

return pop_weight;

}

/* 种群中个体适应度计算*/

double cal_fit(unsigned int *chr)

{

int j;

double pop_profit;//适应度

pop_profit=0;

//  pop_weight=0;

for (j=0;j

{

pop_profit=pop_profit+(*chr)*profit[j];

// pop_weight=pop_weight+(*chr)*weight[j];

chr++;

}

return pop_profit;

}

/* 群体适应度的最大最小值以及其他信息 */

void statistics(struct population *pop)

{

int i;

double tmp_fit;

sumfitness=pop[0].fitness;

minfitness=pop[0].fitness;

minpop=0;

maxfitness=pop[0].fitness;

maxpop=0;

for (i=1;i

{

//计算种群的总适应度

sumfitness=sumfitness+pop[i].fitness;

tmp_fit=pop[i].fitness;

//选择种群中最大适应度的个体

if ((tmp_fit>maxfitness)&&((int)(tmp_fit*10)%10==0))

{

maxfitness=pop[i].fitness;

maxpop=i;

}

//选择种群中最小适应度的个体

if (tmp_fit

{

minfitness=pop[i].fitness;

minpop=i;

}

//计算平均适应度

avgfitness=sumfitness/(float)popsize;

}

//  printf("\nthe max pop = %d;",maxpop);

//  printf("\nthe min pop = %d;",minpop);

//   printf("\nthe sumfitness = %f\n",sumfitness);

}

//报告种群信息

void report(struct population *pop,int gen)

{

int j;

int pop_weight=0;

printf("the generation is %d.\n",gen); //输出种群的代数

//输出种群中最大适应度个体的染色体信息

printf("The population's chrom is:  \n");

for (j=0;j

{

if (j%5==0)

{  printf(" ");}

printf("%1d",pop[maxpop].chrom[j]);

}

//输出群体中最大适应度

printf("\nThe population's max fitness is %d.",(int)pop[maxpop].fitness);

printf("\nThe knapsack weight is %d.\n\n",(int)pop[maxpop].weight);

}

/* 生成初始种群 */

void initpop()

{

int i,j,ispop;

double tmpWeight;

//变量用于判断是否为满足条件的个体

ispop=false;

//生成popsize个种群个体

for(i=0;i

{

while (!ispop)

{

for(j=0;j

{

oldpop[i].chrom[j]=rand()%2;   //随机生成个体的染色体

oldpop[i].parent1=0;  //双亲

oldpop[i].parent2=0;

oldpop[i].cross=0;    //交叉点

}

//选择重量小于背包容量的个体,即满足条件

tmpWeight=cal_weight(oldpop[i].chrom);

if (tmpWeight<=contain)

{

oldpop[i].fitness=cal_fit(oldpop[i].chrom);

oldpop[i].weight=tmpWeight;

oldpop[i].parent1=0;

oldpop[i].parent2=0;

oldpop[i].cross=0;

ispop=true;

}

}

//此个体可以加入到种群中

ispop=false;

}

}

/*  遗传操作   */

//概率选择试验

int execise(double probability)

{

double pp;

//如果生成随机数大于相应的概率则返回真,否则试验不成功

pp=(double)(rand()%20001/20000.0);

if (pp<=probability) return 1;

return 0;

}

// 选择进行交叉操作的个体

int selection(int pop)

{

double wheel_pos,rand_Number,partsum;

int parent;

//赌轮法选择

rand_Number=(rand()%2001)/2000.0;

wheel_pos=rand_Number*sumfitness;  //赌轮大小

partsum=0;

parent=0;

do{

partsum=partsum+oldpop[parent].fitness;

parent=parent+1;

} while (partsum

return parent-1;

}

/*  交叉操作  */

int crossover(unsigned int *parent1,unsigned int *parent2,int i)

{

int j,cross_pos;

if (execise(pc))

{

//生成交叉位置0,1,...(lchrom-2)

cross_pos=rand()%(lchrom-1);

}

else cross_pos=lchrom-1;

for (j=0;j<=cross_pos;j++)

{   //保留复制;

//包括在概率选择不成功时,父体完全保留

newpop[i].chrom[j]=parent1[j];

}

for(j=cross_pos+1;j<=(lchrom-1);j++)

{

//从交叉点开始交叉

newpop[i].chrom[j]=parent2[j];

}

//记录交叉位置

newpop[i].cross=cross_pos;

return 1;

}

/*  变异操作 */

int mutation(unsigned int alleles)

{

if (execise(pm))

{

if (alleles)

alleles=0;

else alleles=1;

}

//返回变异值,或者返回原值

return alleles;

}

/* 群体更新 */

void generation()

{

unsigned int i,j,mate1,mate2;

double tmpWeight;

int ispop;//记录是否是符合条件的个体

i=0;

while (i

{

ispop=false;

while (!ispop)

{

//选择

mate1=selection(i);

mate2=selection(i+1);

//交叉

crossover(oldpop[mate1].chrom,oldpop[mate2].chrom,i);

//变异

for (j=0;j

{

newpop[i].chrom[j]=mutation(newpop[i].chrom[j]);

}

//选择重量小于背包容量的个体,即满足条件

tmpWeight=cal_weight(newpop[i].chrom);

if (tmpWeight<=contain)

{

newpop[i].fitness=cal_fit(newpop[i].chrom);

newpop[i].weight=tmpWeight;

newpop[i].parent1=mate1;

newpop[i].parent2=mate2;

ispop=true;

}

}

//此个体可以加入到种群中

i=i+1;

}

}

void main(int argc, char* argv[])

{

int gen,oldmaxpop,k;

double oldmax;

read_infor();//读入背包信息

gen=0;

srand( (unsigned)time( NULL ) );//置随机种子

initpop();

memcpy(&newpop,&oldpop,popsize*sizeof(struct population));

statistics(newpop);//统计新生种群的信息

report(newpop,gen);

while(gen

{

gen=gen+1;

if (gen%100==0)

{

srand( (unsigned)time( NULL ) );//置随机种子

}

oldmax=maxfitness;

oldmaxpop=maxpop;

generation();

statistics(newpop); //统计新生代种群信息

//如果新生代种群中个体的最大适应度小于老一代种群

//个体的最大适应度,则保存老一代种群个体的最大适应度

//否则报告新生代的最大适应度

if (maxfitness

{

for(k=0;k

newpop[minpop].chrom[k]=oldpop[oldmaxpop].chrom[k];

newpop[minpop].fitness=oldpop[oldmaxpop].fitness;

newpop[minpop].parent1=oldpop[oldmaxpop].parent1;

newpop[minpop].parent2=oldpop[oldmaxpop].parent2;

newpop[minpop].cross=oldpop[oldmaxpop].cross;

statistics(newpop);

}

else if (maxfitness>oldmax)

{

report(newpop,gen);

}

//保存新生代种群的信息到老一代种群信息空间

memcpy(&oldpop,&newpop,popsize*sizeof(struct population));

}

printf("It is over.");

getch();

}

追问:

这个没有贪心算法的,能不能求一个两个相结合的啊???

追答:

背包还能用贪心解吗?

除了这个我只知道搜索和动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值