遗传算法的背包问题c语言

合集下载

数学建模遗传算法例题

数学建模遗传算法例题

数学建模遗传算法例题数学建模中,遗传算法是一种基于进化思想的优化算法,可以应用于复杂的优化问题中。

本文将介绍一些遗传算法的例题,帮助读者更好地理解遗传算法的应用。

例题一:背包问题有一个体积为V的背包和n个物品,第i个物品的体积为vi,价值为wi。

求这个背包最多能装多少价值的物品。

遗传算法的解决步骤:1. 初始化种群:随机生成一定数量的个体作为初始种群。

2. 适应度函数:将每个个体代入适应度函数,计算其适应度值。

3. 选择:根据每个个体的适应度值,选择一定数量的个体进入下一代。

4. 交叉:对被选中的个体进行交叉操作,生成新的个体。

5. 变异:对新的个体进行变异操作,引入新的基因。

6. 重复以上步骤,直到符合终止条件。

在背包问题中,适应度函数可以定义为:背包中物品的总价值。

交叉操作可以选择单点交叉或多点交叉,变异操作可以选择随机变异或非随机变异。

例题二:旅行商问题有n个城市,旅行商需要依次经过这些城市,每个城市之间的距离已知。

求旅行商经过所有城市的最短路径。

遗传算法的解决步骤:1. 初始化种群:随机生成一定数量的个体作为初始种群,每个个体代表一种旅行路线。

2. 适应度函数:将每个个体代入适应度函数,计算其适应度值。

3. 选择:根据每个个体的适应度值,选择一定数量的个体进入下一代。

4. 交叉:对被选中的个体进行交叉操作,生成新的个体。

5. 变异:对新的个体进行变异操作,引入新的基因。

6. 重复以上步骤,直到符合终止条件。

在旅行商问题中,适应度函数可以定义为:旅行商经过所有城市的总距离。

交叉操作可以选择顺序交叉或部分映射交叉,变异操作可以选择交换或反转基因序列。

总结:遗传算法是一种强大的优化算法,可以应用于多种复杂的优化问题中。

在数学建模中,遗传算法的应用也越来越广泛。

本文介绍了背包问题和旅行商问题的遗传算法解决步骤,希望对读者有所帮助。

遗传算法解决01背包问题

遗传算法解决01背包问题

遗传算法解决01背包问题2015 ~2016 学年第二学期学生姓名专业学号2016年 6 月目录一:问题描述 (3)二:遗传算法原理及特点 (3)三:背包问题的遗传算法求解 (3)1.文字描述 (3)2.遗传算法中的抽象概念在背包问题的具体化 (3)3.算法求解的基本步骤 (4)四:算法实现 (4)1.数据结构 (4)2.部分代码 (5)五:结论 (8)六:参考文献 (8)一、问题描述0-1背包问题属于组合优化问题的一个例子,求解0-1背包问题的过程可以被视作在很多可行解当中求解一个最优解。

01背包问题的一般描述如下:给定n个物品和一个背包,物品i的重量为Wi,其价值为Vi,背包的容量为C。

问应如何选择合适的物品装入背包,使得背包中装入的物品的总价值最大。

注意的一点是,背包内的物品的重量之和不能大于背包的容量C。

在选择装入背包的物品时,对每种物品i只有两种选择:即装入背包或者不装入背包,不能讲物品i装入背包多次,也不能只装入部分的物品,称此类问题为0/1背包问题。

二、遗传算法原理及特点遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。

遗传算法有着鲜明的优点:(1)遗传算法的操作对象是一组可行解,而非单个可行解;搜索轨道有多条,而非单条,因而具有良好的并行性.(2)遗传算法只需利用目标的取值信息,而无需递度等高价值信息,因而适用于任何规模,高度非线形的不连续多峰函数的优化以及无解析表达式的目标函数的优化,具有很强的通用性.(3)遗传算法择优机制是一种“软”选择,加上良好的并行性,使它具有良好的全局优化性和稳健性.(4)遗传算法操作的可行解集是经过编码化的(通常采用二进制编码),目标函数解释为编码化个体(可行解)的适应值,因而具有良好的可操作性与简单性.三、背包问题的遗传算法求解1、文字描述0-1背包问题传统的解决方法有动态规划法、分支界限法、回溯法等等。

遗传算法求解背包问题

遗传算法求解背包问题

遗传算法求解背包问题程序实现一、背包问题描述背包问题是著名的NP 完备类困难问题,对这个问题的求解前人已经研究出了不少的经典的方法,对该问题确实能得到很好的结果。

近年来蓬勃发展起来的遗传算法已被广泛地应用于优化领域,其全局最优性、可并行性、高效性在函数优化中得到了广泛地应用遗传算法克服了传统优化方法的缺点,借助了大自然的演化过程,是多线索而非单线索的全局优化方法,采用的是种群和随机搜索机制. 本程序将遗传算法应用于背包问题。

二、实验程序1、编程语言:C++2、开发环境:Microsoft Visual Studio 20053、程序整体流程:步1初始化过程1. 1确定种群规模scale、杂交概率pc、变异概率pm、染色体长度chN及最大进化代数maxgen。

1. 2取x1′(0) = u (0 ,1) , x2′(0) = u (0 ,1) , …, xchN′(0) = u (0 ,1) ,其中函数u (0 ,1) 表示随机地产生数0 或1 ,则x (0) = ( x1 (0) , x2 (0) ,⋯, xN (0) ) .若不满足约束条件,则拒绝接受. 由(1. 2) 重新产生一个新的染色体; 如果产生的染色体可行,则接受它作为种群的一名成员,经过有限次抽样后, 得到scale个可行的染色体xj (0) , j =1 ,2 , ⋯, M ,设xj (0) 的染色体编码为vj (0) ,并记为v (0) = ( v1 (0) , ⋯, vchN (0) ) .1. 3计算各个染色体的适值1. 4 置k = 0步2选择操作2. 1采用转轮法选择下一代。

.步3杂交变异操作3. 1 事先定义杂交操作的概率pc ,为确定杂交操作的父代,从j = 1 到M 重复以下过程:从[0 ,1 ] 中产生随机数r ,若r < pc ,则选择cj′( k)作为一个父代.3. 2 产生两个[1 , N ] 上的随机整数i 、j ,变异的结果为染色体vj′( k)的第i 位基因的值变为其第j 位基因的值,同样将染色体的vj′( k)第j 位基因的值变为其第i 位基因的值.3. 3 检验该染色体的可行性,若可行则作为变异的结果;如不可行,重复3. 2 直至该染色体可行.3. 4 事先定义变异概率pm ,对经过杂交操作的中间个体进行变异操作: ,如果r < pm ,则选择vi″( k) 作为变异的父代.3. 5 产生一个[1 , N ] 上的随机整数i ,及随机地产生数0 或1 , 记为b , 变异的结果为染色体vi″( k) 的第i 位基因的值变为b.3. 6 检验该染色体的可行性,若可行则作为变异的结果:如不可行,重复3. 5 直至该染色体可行.3. 7 计算新个体的适应值,并把它们同时放回,和步2 选择操作中剩余的个体一起构成新一代种群v ( k + 1) = { v1 ( k + 1) , v2 ( k + 1) , ⋯, vM ( k + 1) } .步4 终止检验如果达到最大进化代数maxgen 则终止演化,否则置k : = k + 1 ,转步2.4、程序流程图程序流程图5、程序代码1)主程序代码:KnapsacksProblem.cpp文件#include "GAonKP.h"#include <iostream>using namespace std;void main(){FILE* fp;CGAonKP gakp;int scale; //种群规模double MaxWeight; //背包允许最大财宝质量double pc; //杂交概率double pm; //变异概率int maxgen; //最大进化代数char filename[256];cout<<"遗传算法解决背包问题程序使用说明:"<<endl;cout<<"1、该背包问题采用遗传算法"<<endl;cout<<"2、-1编码的方法,其中代表选中所对应的物品,代表不选中该物品"<<endl;cout<<"3、背包允许最带重量,种群规模(解空间大小),";cout<<"杂交概率,变异概率,最大进化代数需自己给";cout<<"定,程序会提示输入"<<endl;cout<<"4、程序提供一个输入示例"<<endl;cout<<"5、输入文件可加单行或多行注释"<<endl;cout<<"例如:#添加单行注释内容#"<<endl;cout<<"例如:#添加多行注释内容"<<endl;cout<<" 添加多行注释内容#"<<endl;cout<<"6、输入文件头位置需指定物品个数为int型数据。

遗传算法求解背包问题

遗传算法求解背包问题

遗传算法的过程:初始化:将计划装入背包的每个物品看成一个二进制串的一位,为1表示放入该物品,为0表示不放入该物品。

初始种群的产生:初始化前对放入背包物品数的一个预测(背包容积/物品最大体积),接下来只要在种群每条染色体中保证有(背包容积/物品最大体积)个为1的位初始化就完成了。

选择:选择进行杂交的父代染色体,被选中的父代染色体总是若干个染色体中最优(适应度最高)的,来保证向优化的方向发展。

详细的选择方法:随机产生2个数:Chrom_Cross_From, Chrom_Cross_To,当然得采用一定的手段来保证前者比后者小。

从Chrom_Cross_From到Chrom_Cross_To这Chrom_Cross_To-Chrom_Cross_From+1条染色体中选择最优(适应度最大)的染色体作为父代之一。

需要进行两次选择得到杂交的两条父代染色体。

这样做可以保证算法不会过早收敛。

函数实现:Individual Select(int ChromSize,Individual Pop[]){int Num_Selected,i,j,Chrom_Selected_From,Chrom_Selected_To,temp;Individual *Chrom_Selected;do{Chrom_Selected_From=rand()%PopSize;Chrom_Selected_To=rand()%PopSize;if(Chrom_Selected_From>Chrom_Selected_To){temp=Chrom_Selected_From;Chrom_Selected_From=Chrom_Selected_To;Chrom_Selected_To=temp;}Num_Selected=Chrom_Selected_To-Chrom_Selected_From+1;}while(Num_Selected<=0);Chrom_Selected=new Individual[Num_Selected];for(i=0;i<Num_Selected;i++)Chrom_Selected[i].chrom=new int[ChromSize];for(i=0,j=Chrom_Selected_From;i<Num_Selected,j<Chrom_Selected_To+1;i++,j++){Chrom_Selected[i]=Pop[j];}Order_Best_First(ChromSize,Num_Selected,Chrom_Selected);Chrom_Selected[0].fitness=Fitness(Chrom_Selected[0].chrom,ChromSize);return Chrom_Selected[0];}杂交:将两次选择得到的父代染色体进行杂交得到一条新的染色体,作为较新种群(并非新的种群)的一条染色体,杂交直到较新种群的染色体数等于原种群的染色体数。

01背包问题c语言代码回溯法

01背包问题c语言代码回溯法

以下是使用C语言实现01背包问题的回溯法代码:```c#include <stdio.h>#include <stdlib.h>// 初始化背包struct knapsack {int maxWeight; // 背包最大承重int *items; // 物品数组int n; // 物品数量};// 定义物品重量、价值和数量int weights[] = {2, 2, 6, 5, 4};int values[] = {6, 3, 5, 4, 6};int quantities[] = {3, 2, 2, 1, 1};// 初始化背包最大承重和当前承重int maxWeight = 10;int currentWeight = 0;// 初始化最大价值为0int maxValue = 0;// 遍历物品数组void traverseItems(struct knapsack *knapsack, int index) { // 对于每个物品,遍历其数量for (int i = 0; i < knapsack->quantities[index]; i++) {// 如果当前物品可以放入背包装且当前承重不超过背包最大承重,计算放入该物品后的总价值,并更新最大价值if (currentWeight + weights[index] <= knapsack->maxWeight) {int currentValue = values[index] * knapsack->quantities[index];if (currentValue > maxValue) {maxValue = currentValue;}}// 回溯,将当前物品从背包装中移除,递归地尝试下一个物品knapsack->quantities[index]--;if (index < knapsack->n - 1) {traverseItems(knapsack, index + 1);}knapsack->quantities[index]++; // 恢复物品数量,以便下次遍历尝试放入其他物品}}// 主函数int main() {// 初始化背包装和物品数组struct knapsack knapsack = {maxWeight, weights, 5};knapsack.items = (int *)malloc(sizeof(int) * knapsack.n);for (int i = 0; i < knapsack.n; i++) {knapsack.items[i] = values[i] * quantities[i]; // 根据价值和数量计算物品价值,并存储在物品数组中}knapsack.n = quantities[4]; // 由于最后一个物品的数量为1,因此只需遍历前n-1个物品即可得到所有可能的结果// 使用回溯法求解01背包问题,返回最大价值traverseItems(&knapsack, 0);printf("The maximum value is %d.\n", maxValue);free(knapsack.items); // 释放内存空间return 0;}```希望以上信息能帮助到你。

遗传算法的C语言实现(二)-----以求解TSP问题为例

遗传算法的C语言实现(二)-----以求解TSP问题为例

遗传算法的C语⾔实现(⼆)-----以求解TSP问题为例上⼀次我们使⽤遗传算法求解了⼀个较为复杂的多元⾮线性函数的极值问题,也基本了解了遗传算法的实现基本步骤。

这⼀次,我再以经典的TSP问题为例,更加深⼊地说明遗传算法中选择、交叉、变异等核⼼步骤的实现。

⽽且这⼀次解决的是离散型问题,上⼀次解决的是连续型问题,刚好形成对照。

⾸先介绍⼀下TSP问题。

TSP(traveling salesman problem,旅⾏商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增⼤按指数⽅式增长,到⽬前为⽌还没有找到⼀个多项式时间的有效算法。

TSP问题可以描述为:已知n个城市之间的相互距离,某⼀旅⾏商从某⼀个城市出发,访问每个城市⼀次且仅⼀次,最后回到出发的城市,如何安排才能使其所⾛的路线最短。

换⾔之,就是寻找⼀条遍历n个城市的路径,或者说搜索⾃然⼦集X={1,2,...,n}(X的元素表⽰对n个城市的编号)的⼀个排列P(X)={V1,V2,....,Vn},使得Td=∑d(V i,V i+1)+d(V n,V1)取最⼩值,其中,d(V i,V i+1)表⽰城市V i到V i+1的距离。

TSP问题不仅仅是旅⾏商问题,其他许多NP完全问题也可以归结为TSP问题,如邮路问题,装配线上的螺母问题和产品的⽣产安排问题等等,也使得TSP问题的求解具有更加⼴泛的实际意义。

再来说针对TSP问题使⽤遗传算法的步骤。

(1)编码问题:由于这是⼀个离散型的问题,我们采⽤整数编码的⽅式,⽤1~n来表⽰n个城市,1~n的任意⼀个排列就构成了问题的⼀个解。

可以知道,对于n个城市的TSP问题,⼀共有n!种不同的路线。

(2)种群初始化:对于N个个体的种群,随机给出N个问题的解(相当于是染⾊体)作为初始种群。

这⾥具体采⽤的⽅法是:1,2,...,n作为第⼀个个体,然后2,3,..n分别与1交换位置得到n-1个解,从2开始,3,4,...,n分别与2交换位置得到n-2个解,依次类推。

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---0/1背包问题在0 / 1背包问题中,需对容量为c 的背包进行装载。

从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。

对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即n ?i=1pi xi 取得最大值。

约束条件为n ?i =1wi xi≤c 和xi?[ 0 , 1 ] ( 1≤i≤n)。

在这个表达式中,需求出xt 的值。

xi = 1表示物品i 装入背包中,xi =0 表示物品i 不装入背包。

0 / 1背包问题是一个一般化的货箱装载问题,即每个货箱所获得的价值不同。

货箱装载问题转化为背包问题的形式为:船作为背包,货箱作为可装入背包的物品。

例1-8 在杂货店比赛中你获得了第一名,奖品是一车免费杂货。

店中有n 种不同的货物。

规则规定从每种货物中最多只能拿一件,车子的容量为c,物品i 需占用wi 的空间,价值为pi 。

你的目标是使车中装载的物品价值最大。

当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。

这个问题可仿照0 / 1背包问题进行建模,其中车对应于背包,货物对应于物品。

0 / 1背包问题有好几种贪婪策略,每个贪婪策略都采用多步过程来完成背包的装入。

在每一步过程中利用贪婪准则选择一个物品装入背包。

一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。

这种策略不能保证得到最优解。

例如,考虑n=2, w=[100,10,10], p =[20,15,15], c = 1 0 5。

当利用价值贪婪准则时,获得的解为x= [ 1 , 0 , 0 ],这种方案的总价值为2 0。

而最优解为[ 0 , 1 , 1 ],其总价值为3 0。

另一种方案是重量贪婪准则是:从剩下的物品中选择可装入背包的重量最小的物品。

ACM背包问题

ACM背包问题
第4 章
背包问题
如果给你一个背包,要你从许多东西里选择一些装进来,只要这个包装得下,你就可 以将包里的东西全部拿走了,那么你会如何选择物品呢?这里你需要考虑的是背包的体积 和承重限制,当然最重要的是你拿走的东西的总价值最大。这样的问题就是背包问题,许 多问题都可以转化为背包问题来考虑。背包问题是一个在运筹学领域里常见的典型 NP-C 难题,对该问题的求解方法的研究无论是在理论上,还是在实践中都具有一定的意义。
while (goods[0].flag<goods[i].flag) {
goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } ///////////////////////////////////////////
·78·
第 4 章 背包问题
cout<<"最优解为:"<<endl; for(i=1;i<=n;i++) {
4.3.1 〖案例 2〗0/1 背包
需对容量为 c 的背包进行装载。从 n 个物品中选取装入背包的物品,每件物品 i 的重 量为 wi,价值为 pi。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最 佳装载是指所装入的物品价值最高。限制:每个物品不能被分割,要不被装载,要不不被 装载。
第一行物品个数,接下来分别为物品价值,再接下来分别为物品的价值。再接下来分 别为物品的重量,最后为背包的容量。
数据结构与算法: 不需要特殊的数据结构 算法采用贪婪法 首先输入物品信息和背包容量,然后每次选比重最大的装载。
struct goodinfo
{ float p; float w; float X; int flag;

C语言动态规划之背包问题详解

C语言动态规划之背包问题详解

C语⾔动态规划之背包问题详解01背包问题给定n种物品,和⼀个容量为C的背包,物品i的重量是w[i],其价值为v[i]。

问如何选择装⼊背包的物品,使得装⼊背包中的总价值最⼤?(⾯对每个武平,只能有选择拿取或者不拿两种选择,不能选择装⼊某物品的⼀部分,也不能装⼊物品多次)声明⼀个数组f[n][c]的⼆维数组,f[i][j]表⽰在⾯对第i件物品,且背包容量为j时所能获得的最⼤价值。

根据题⽬要求进⾏打表查找相关的边界和规律根据打表列写相关的状态转移⽅程⽤程序实现状态转移⽅程真题演练:⼀个旅⾏者有⼀个最多能装M公⽄的背包,现在有n件物品,它们的重量分别是W1、W2、W3、W4、…、Wn。

它们的价值分别是C1、C3、C2、…、Cn,求旅⾏者能获得最⼤价值。

输⼊描述:第⼀⾏:两个整数,M(背包容量,M<= 200)和N(物品数量,N<=30);第2…N+1⾏:每⾏两个整数Wi,Ci,表⽰每个物品的质量与价值。

输出描述:仅⼀⾏,⼀个数,表⽰最⼤总价值样例:输⼊:10 42 13 34 57 9输出:12解题步骤定义⼀个数组dp[i][j]表⽰容量为j时,拿第i个物品时所能获取的最⼤价值。

按照题⽬要求进⾏打表,列出对应的dp表。

W[i](质量)V[i](价值)01234567891000000000000210011111111133001334444444500135568899790013556991012对于⼀个动态规划问题设置下标时最好从0开始,因为动态规划经常会和上⼀个状态有关系!从上⾯的dp表可以看出来对于⼀个物品我们拿还是不难需要进⾏两步来判断。

第⼀步:判断背包当前的容量j是否⼤于物品当前的质量,如果物品的质量⼤于背包的容量那么就舍弃。

第⼆步:如果背包可以装下这个物品,就需要判断装下该物品获取的最⼤价值是不是⼤于不装下这个物品所获取的最⼤价值,如果⼤于那么就把东西装下!根据这样的思想我们可以得到状态转移⽅程:如果单签背包的容量可以装下物品:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);如果当前背包的容量装不下该物品:dp[i][j]=dp[i-1][j];#include <stdio.h>int max(const int a,const int b){return a>b ? a:b;}int main(){int w[35]={0},v[35]={0},dp[35][210]={0};int n,m;scanf("%d %d",&m,&n);int i,j;for(i=1;i<=n;i++){scanf("%d %d",&w[i],&v[i]);}for(i=1;i<=n;i++){for(j=1;j<=m;j++){if(j>=w[i])//如果当前背包的容量⼤于商品的质量{dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//判断是否应该拿下}else//⼤于背包的当前容量{dp[i][j]=dp[i-1][j];}}}for(int k=0;k<=n;k++){for(int l=0;l<=m;l++){printf("%d ",dp[k][l]);}printf("\n");}printf("%d\n",dp[n][m]);}通过运⾏以上程序可以看到最终的输出dp表和我们的预期是相符合的!但是并没有结束,动态规划有⼀个后⽆效性原则(当前状态只与前⼀个状态有关)。

0-1背包问题动态规划详解及代码

0-1背包问题动态规划详解及代码

0/1 背包问题动态规划详解及C代码动态规划是用空间换时间的一种方法的抽象。

其关键是发现子问题和记录其结果。

然后利用这些结果减轻运算量。

比如01背包问题。

/* 一个旅行者有一个最多能用M公斤的背包,现在有N件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为P1,P2,...,Pn.若每种物品只有一件求旅行者能获得最大总价值。

输入格式:M,NW1,P1W2,P2......输出格式:X*/因为背包最大容量M未知。

所以,我们的程序要从1到M一个一个的试。

比如,开始任选N 件物品的一个。

看对应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则,多出来的空间里能放N-1物品中的最大价值。

怎么能保证总选择是最大价值呢?看下表。

测试数据:10,33,44,55,6c[i][j]数组保存了1,2,3号物品依次选择后的最大价值.这个最大价值是怎么得来的呢?从背包容量为0开始,1号物品先试,0,1,2,的容量都不能放.所以置0,背包容量为3则里面放4.这样,这一排背包容量为4,5,6,....10的时候,最佳方案都是放4.假如1号物品放入背包.则再看2号物品.当背包容量为3的时候,最佳方案还是上一排的最价方案c为4.而背包容量为5的时候,则最佳方案为自己的重量5.背包容量为7的时候,很显然是5加上一个值了。

加谁??很显然是7-4=3的时候.上一排 c3的最佳方案是4.所以。

总的最佳方案是5+4为9.这样.一排一排推下去。

最右下放的数据就是最大的价值了。

(注意第3排的背包容量为7的时候,最佳方案不是本身的6.而是上一排的9.说明这时候3号物品没有被选.选的是1,2号物品.所以得9.)从以上最大价值的构造过程中可以看出。

f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}这就是书本上写的动态规划方程.这回清楚了吗?下面是实际程序(在VC 6.0环境下通过):#include<stdio.h>int c[10][100];/*对应每种情况的最大价值*/int knapsack(int m,int n){int i,j,w[10],p[10];printf("请输入每个物品的重量,价值:\n");for(i=1;i<=n;i++)scanf("%d,%d",&w[i],&p[i]);for(i=0;i<10;i++)for(j=0;j<100;j++)c[i][j]=0;/*初始化数组*/for(i=1;i<=n;i++)for(j=1;j<=m;j++){if(w[i]<=j) /*如果当前物品的容量小于背包容量*/{if(p[i]+c[i-1][j-w[i]]>c[i-1][j])/*如果本物品的价值加上背包剩下的空间能放的物品的价值*//*大于上一次选择的最佳方案则更新c[i][j]*/c[i][j]=p[i]+c[i-1][j-w[i]];elsec[i][j]=c[i-1][j];}else c[i][j]=c[i-1][j];}return(c[n][m]);}int main(){int m,n;int i,j;printf("请输入背包的承重量,物品的总个数:\n");scanf("%d,%d",&m,&n);printf("旅行者背包能装的最大总价值为%d",knapsack(m,n)); printf("\n");return 0;}。

遗传算法求解0-1背包问题(步骤)(精)

遗传算法求解0-1背包问题(步骤)(精)

遗传算法求解0-1背包问题。

(步骤)#include "iostream.h"#include "iomanip.h"#include "stdlib.h"#include "math.h"#include "time.h"//定义问题的最大规模#define max 100//问题规模,即共有多少个包int packageNum;//每个包的重量int packageWeight[max];//每个包的价值int packageValue[max];//约束,背包的最大容量int limitWeight;//群体的规模int colonySize;//colonyState[i][k] 表示一个染色体//colonyState[1...colonySize][ 0|1 ] 表示一代群体int colonyState[max][2][max];// currAge 表示当前代的编号// (currAge+1)%2 表示下一代的编号int currAge = 0;//个体评价信息表typedef struct tagIndividualMsg{int index;int value;} IndividualMsg;IndividualMsg individualMsg[max];//////////////////////////////////////////////////////////// // 函数声明void printColonyState( int nextAge );//////////////////////////////////////////////////////////// //初始化群体void colonyInit(){int i , j;int w;for( i = 0 ; i < colonySize ; i++ ){//保证找到一个符合约束的染色体w = limitWeight + 1;while( w > limitWeight ){w = 0;for( j = 0 ; j < packageNum && w <= limitWeight ; j++ ){colonyState[i][currAge][j] = rand() % 2;w += packageWeight[j] * colonyState[i][currAge][j];}}}}//对个体进行评价int cmp( const void *a , const void *b ){IndividualMsg *x = (IndividualMsg *)a;IndividualMsg *y = (IndividualMsg *)b;return y->value - x->value;}void individualEstimate(){int i , j;for( i = 0 ; i < colonySize ; i++ ){individualMsg[i].index = i;individualMsg[i].value = 0;for( j = 0 ; j < packageNum ; j++ )individualMsg[i].value += packageValue[j] * colonyState[i][currAge][j]; }qsort( individualMsg , colonySize , sizeof(IndividualMsg) , cmp );}//终止循环的条件bool stopFlag(){//进行n 代进行后停止static int n = 50;if( n-- <= 0 )return true;elsereturn false;}//赌轮选择int gambleChoose(){int wheel[max] = { 0 };int i = colonySize - 1;int choose;wheel[i] = individualMsg[i].value;for( i-- ; i >= 0 ; i-- )wheel[i] = ( individualMsg[i].value + wheel[i+1] ) + colonySize * ( colonySize - i ); int seed = abs( wheel[0] - ( rand() % ( 2 * wheel[0] ) + 1 ) );choose = colonySize - 1;while( seed > wheel[choose] )choose--;// cout<<"----------------------------------------"<<endl;// cout<<"wheel :"<<endl;// for( i = 0 ; i < colonySize ; i++ )// cout<<setw(5)<<wheel[i];// cout<<endl;// cout<<"seed = "<<seed<<endl;// cout<<"choose "<<choose<<endl;return choose;}//交叉void across( int male , int female , int index ){int nextAge = (currAge+1)%2;int i , j , t;int acrossBit = rand() % (packageNum-1) + 1;for( j = 0 ; j < packageNum ; j++ ){colonyState[index][nextAge][j] =colonyState[individualMsg[male].index][currAge][j];colonyState[index+1][nextAge][j] =colonyState[individualMsg[female].index][currAge][j];}for( i = 0 ; i < acrossBit ; i++ ){t = colonyState[index][nextAge][i];colonyState[index][nextAge][i] = colonyState[index+1][nextAge][i];colonyState[index+1][nextAge][j] = t;}}//变异void aberrance( int index ){int seed , nextAge;nextAge = (currAge+1)%2;//只有1/3 的概率发生异变seed = rand() % ( packageNum * 3 );if( seed < packageNum )colonyState[index][nextAge][seed] = ( colonyState[index][nextAge][seed] + 1 ) % 2;}//处理死亡个体void dealDeath(){int i , j;int weight , w;int nextAge = (currAge+1)%2;for( i = 0 ; i < colonySize ; i++ ){weight = 0;for( j = 0 ; j < packageNum ; j++ )weight += packageWeight[j] * colonyState[i][nextAge][j];if( weight > limitWeight ){//随机生成新的个体w = limitWeight + 1;while( w > limitWeight ){w = 0;for( j = 0 ; j < packageNum && w <= limitWeight ; j++ ){colonyState[i][nextAge][j] = rand() % 2;w += packageWeight[j] * colonyState[i][nextAge][j];}}}}printColonyState( nextAge );}//最优个体保护void saveBest(){int i , j;int min , minp , value;int nextAge = ( currAge+1)%2;min = individualMsg[0].value;minp = -1;for( i = 0 ; i < colonySize ; i++ ){value = 0;for( j = 0 ; j < packageNum ; j++ )value += packageValue[j] * colonyState[i][nextAge][j]; if( value <= min ){min = value;minp = i;}}if( minp >= 0 ){for( j = 0 ; j < packageNum ; j++ ){colonyState[minp][nextAge][j] =colonyState[individualMsg[0].index][currAge][j];}}}//////////////////////////////////////////////////////////// void setProblem(){int i;packageNum = 5;int w[] = { 5 , 4 , 3 , 2 , 1 };int v[] = { 8 , 9 , 3 , 1 , 2 };for( i = 0 ; i < packageNum ; i++ ){packageWeight[i] = w[i];packageValue[i] = v[i];}limitWeight = 13;colonySize = 5;}void printProblem(){int i;cout<<"----------------------------------------"<<endl;cout<<"problem state:"<<endl;cout<<"packageNum = "<<packageNum<<endl;cout<<"limitWeight = "<<limitWeight<<endl;cout<<"Weight: ";for( i = 0 ; i < packageNum ; i++ )cout<<setw(3)<<packageWeight[i];cout<<endl;cout<<"Value: ";for( i = 0 ; i < packageNum ; i++ )cout<<setw(3)<<packageValue[i];cout<<endl;}void printColonyState( int k ){cout<<"----------------------------------------"<<endl;cout<<"colonyState-->";if( k == currAge )cout<<"currAge:"<<endl;elsecout<<"next age:"<<endl;int i , j;for( i = 0 ; i < colonySize ; i++ ){for( j = 0 ; j < packageNum ; j++ )cout<<setw(2)<<colonyState[i][k][j];cout<<endl;}}void printIndividualMsg(){int i;cout<<"----------------------------------------"<<endl;cout<<"Individual Msg:"<<endl;for( i = 0 ; i < colonySize ; i++ ){cout<<individualMsg[i].index<<"\t"<<individualMsg[i].value<<endl; }}////////////////////////////////////////////////////////////void main(){srand( (unsigned int)time(NULL) );setProblem();printProblem();//初始群体colonyInit();printColonyState( currAge );while( !stopFlag() ){//评价当前群体individualEstimate();//生成下一代for( int i = 0 ; i < colonySize ; i += 2 ){int male = gambleChoose();int female = gambleChoose();across( male , female , i );aberrance( i );aberrance( i + 1 );}//处理死亡个体dealDeath();//最优个体保护saveBest();//现在的下一代变成下一轮的当前代currAge = ( currAge + 1 ) % 2;//printColonyState( currAge );}//输出问题解individualEstimate();cout<<"近似解:"<<endl;int j , w = 0;cout<<setw(10)<<"Value:";for( j = 0 ; j < packageNum ; j++ )cout<<setw(5)<<packageValue[j];cout<<endl;cout<<setw(10)<<"Weight:";for( j = 0 ; j < packageNum ; j++ ){w += packageWeight[j] * colonyState[individualMsg[0].index][currAge][j]; cout<<setw(5)<<packageWeight[j];}cout<<endl;cout<<setw(10)<<"Choose:";for( j = 0 ; j < packageNum ; j++ )cout<<setw(5)<<colonyState[individualMsg[0].index][currAge][j];cout<<endl;cout<<"limitWeight: "<<limitWeight<<endl;cout<<"总重量: "<<w<<endl;cout<<"总价值: "<<individualMsg[0].value<<endl; }////////////////////////////////////////////////////////////。

遗传算法 c语言代码

遗传算法 c语言代码

以下是一个简单的遗传算法的C语言代码示例:c#include <stdio.h>#include <stdlib.h>#include <time.h>#include <math.h>#define POPULATION_SIZE 100#define GENE_LENGTH 10#define MAX_GENERATIONS 1000#define MUTATION_RATE 0.01#define CROSSOVER_RATE 0.8typedef struct Individual {char genes[GENE_LENGTH];double fitness;} Individual;double calculate_fitness(Individual* individual) {// 计算适应度函数,这里使用简单的二进制字符串中1的个数作为适应度 int count = 0;for (int i = 0; i < GENE_LENGTH; i++) {if (individual->genes[i] == '1') {count++;}}return count;}void initialize_population(Individual* population) {// 初始化种群for (int i = 0; i < POPULATION_SIZE; i++) {for (int j = 0; j < GENE_LENGTH; j++) {population[i].genes[j] = rand() % 2 ? '0' : '1';}population[i].fitness = calculate_fitness(&population[i]); }}void selection(Individual* population, Individual* parents) {// 选择操作,采用轮盘赌算法选择两个父代个体double total_fitness = 0;for (int i = 0; i < POPULATION_SIZE; i++) {total_fitness += population[i].fitness;}double rand1 = rand() / (double)RAND_MAX * total_fitness;double rand2 = rand() / (double)RAND_MAX * total_fitness;double cumulative_fitness = 0;int parent1_index = -1, parent2_index = -1;for (int i = 0; i < POPULATION_SIZE; i++) {cumulative_fitness += population[i].fitness;if (rand1 < cumulative_fitness && parent1_index == -1) {parent1_index = i;}if (rand2 < cumulative_fitness && parent2_index == -1) {parent2_index = i;}}parents[0] = population[parent1_index];parents[1] = population[parent2_index];}void crossover(Individual* parents, Individual* offspring) {// 交叉操作,采用单点交叉算法生成两个子代个体int crossover_point = rand() % GENE_LENGTH;for (int i = 0; i < crossover_point; i++) {offspring[0].genes[i] = parents[0].genes[i];offspring[1].genes[i] = parents[1].genes[i];}for (int i = crossover_point; i < GENE_LENGTH; i++) {offspring[0].genes[i] = parents[1].genes[i];offspring[1].genes[i] = parents[0].genes[i];}offspring[0].fitness = calculate_fitness(&offspring[0]);offspring[1].fitness = calculate_fitness(&offspring[1]);}void mutation(Individual* individual) {// 变异操作,以一定概率翻转基因位上的值for (int i = 0; i < GENE_LENGTH; i++) {if (rand() / (double)RAND_MAX < MUTATION_RATE) {individual->genes[i] = individual->genes[i] == '0' ? '1' : '0'; }}individual->fitness = calculate_fitness(individual);}void replace(Individual* population, Individual* offspring) {// 替换操作,将两个子代个体中适应度更高的一个替换掉种群中适应度最低的一个个体int worst_index = -1;double worst_fitness = INFINITY;for (int i = 0; i < POPULATION_SIZE; i++) {if (population[i].fitness < worst_fitness) {worst_index = i;worst_fitness = population[i].fitness;}}if (offspring[0].fitness > worst_fitness || offspring[1].fitness > worst_fitness) {if (offspring[0].fitness > offspring[1].fitness) {population[worst_index] = offspring[0];} else {population[worst_index] = offspring[1];}}}。

遗传算法求解01背包问题

遗传算法求解01背包问题

遗传算法求解01背包问题一、问题描述01背包问题属于组合优化问题的一个例子,求解01背包问题的过程可以被视作在很多可行解当中求解一个最优解。

01背包问题的一般描述如下:给定n个物品和一个背包,物品i的重量为W i,其价值为V i,背包的容量为C。

选择合适的物品装入背包,使得背包中装入的物品的总价值最大。

注意的一点是,背包内的物品的重量之和不能大于背包的容量C。

在选择装入背包的物品时,对每种物品i只有两种选择:装入背包或者不装入背包,即只能将物品i装入背包一次。

称此类问题为0/1背包问题。

01背包问题是NP问题,传统的解决方法有动态规划法、分支界限法、回溯法等等。

传统的方法不能有效地解决01背包问题。

遗传算法(Genetic Algorithms)则是一种适合于在大量的可行解中搜索最优(或次优)解的有效算法。

二、遗传算法1、遗传算法的基本思想遗传算法的搜索从一个被称作种群的候选解集开始,新的种群由旧的种群中产生以期得到更好的种群。

从旧种群中按照解的适应度来选择解以产生新的解;适应度越大,解被选择生成后代的机率也越大。

这个从已有种群中选择双亲并产生后代的迭代过程持续到遗传算法的停止条件满足为止。

2、遗传算法的基本元素。

遗传算法由以下几个原素组成:由染色体组成的种群,根据适应度进行选择以及交叉产生后代。

三、用遗传算法求解01背包问题1、01背包问题中染色体的表示。

用向量X来表示染色体,X = {x1,x2,……,x n}。

,x i∈{0,1},x i=1表示物品i装入了背包,x i =0表示物品i未装入背包。

每个染色体对应其当前装入背包的物品的总价值和总重量。

背包中物品的中价值代表了该物品的适应度。

程序中定义了这样的一个结构来表示染色体:typedef struct{int Weight; //染色体代表的物品的总重量int Fitness; //染色体代表的物品的价值(适应度)int Gene[NUMG]; //用元素取值于定义域{0,1}的数组表示染色体。

基于遗传算法求解背包问题的算法探讨

基于遗传算法求解背包问题的算法探讨

述这些算法容易陷入局部最优解 , 或者收敛速度太慢而不实用.
Байду номын сангаас

2 解 决 01 1 背包 问题 的遗传 算 法
遗传算法 是由美国 Mi i n c g 大学的 J ol d ha . l n 教授 于 17 年首次提出的 , H a 95 它是 一种借 鉴 自然的选 择机制的搜索算法. 遗传算法 的实现过程 主要包 括编码 、 生种群 、 产 计算适应 度 、 复制 、 交换 、 变异等操作. 概括地讲 , 对于 01 / 背包问题利用遗传
r c r ie l o i m a d l sr t s h t e e i ag rtm i f a i l a d f ce t o o v t e n p a k e u sv ag rt h n i u t e t a g n t l a c loi h s e sb e n ef in t s l e h k a s c i
( .o e e o o p t c n e a d T c n lg , n r Mo g l nv ri rN t n l is o gi 2 0 3 1 l g fC m ue S i c n e h oo y n e n o a U i s y f ai a t , n l o 0 8 4 , C l r e I i e t o o ie T a
的方法 , 确算法有 : 精 分支一 定界算法 , 动态规划算法等 _ 启发式算法有 : 贪心算法 , 模拟退火算法 等. 这些算法在一定程 度上
解 决 了0 l 一 背包问题 , 但也有一 些缺陷 , 如枚举算 法对于规模 较小 的问题 比较有效 , 对大规模 的问题不易求解 . 而 另外 , 上

蛮力法解决0_1背包问题新思路-——利用C语言位域类型

蛮力法解决0_1背包问题新思路-——利用C语言位域类型
运行结果
package.state=state; totalWeight=package.flags.good_1_flag*weight[0]+package.flags.good_2_flag*weight[1] +package.flags.good_3_flag*weight[2]+package.flags.good_4_flag*weight[3] +package.flags.good_5_flag*weight[4]; if(totalWeight<=CAPACITY) { totalValue=package.flags.good_1_flag*value[0]+package.flags.good_2_flag*value[1]
+package.flags.good_3_flag*value[2]+package.flags.good_4_flag*value[3] +package.flags.good_5_flag*value[4]; if(maxValue<totalValue) { maxValue=totalValue; position=state; } } } package.sta=%d\ngood state:%d %d %d %d %d \n",maxValue,package.flags.good_1_flag, package.flags.good_2_flag,package.flags.good_3_flag,package.flags.good_4_flag,package.flags.good_5_flag); return 0; }
登录后才能查看或发表评论立即登录或者逛逛博客园首页

“遗传算法”解决“背包问题”

“遗传算法”解决“背包问题”

“遗传算法”解决“背包问题”遗传算法基本思想:1) ⼀个种群有多个个体,每个个体有染⾊体和对应的基因为了繁殖进⾏:2) 选择:在残酷的世界中,适者⽣存,优胜略汰。

3) 重组:染⾊体交叉,基因重组4) 突变:染⾊体上的基因⼩概率的突变(⼀般给⼩数点后两位)背包问题:背包只能容得下⼀定重量b的物品,物品有m种,每种物品有⾃⼰的重量w(i)和价值v(i)(0<i<=m),从这些物品中选择装⼊背包,是背包不超过重量b,但价值⼜要最⼤。

运⽤动态规划,分⽀限界都可以达到效果,但不佳。

我⽤遗传算法解决:⼀般⼈有多条染⾊体,但对于背包问题,⼀个解我们将看成⼀个个体,所以,⼀个个体只有⼀个染⾊体,⼀个染⾊体对应多个基因。

如:100101010100111 表⽰装⼊背包的可能解。

(具体情况具体分析)遗传所做准备:1) ⽤0表⽰“不选择装⼊”,1表⽰“装⼊”,形成⼀条基因链;100101010100111则表⽰“15种物品”装⼊或不装⼊背包的可能解。

------- 此处⽤chrom[]存放基因,代表染⾊体2) ⼀个基因对应⼀个个体。

------- 此处⽤Population类或结构体声明其含有chrom[]等信息3) 可能的解有很多,构成⼀个种群。

------- ⽤Population类定义⼀个数组代表个体构成的种群newPop[]:存放新⽣代,oldPop[]:存放上⼀代4) 适应度:适应度和⽬标函数是正相关的,所以需要物品价值和重量。

------- fitness,weight包含在Population类中最⼤适应度:maxFitness,最⼩适应度:minFitness,总适应度:sumFitness,(帮助求突变和交叉的染⾊体)平均适应度:avgFitness遗传算法的函数:基本:1) InitPop() 初始化个体,使每个个体都有基因组2) Statistics(*pop) 计算适应度(最⼤,最⼩,总的,平均的)3) Selection(*pop) 通过选择种群中符合要求的⽗母去繁殖新代,返回这对⽗母的位置4) crossover(*parent1,*parent2,pos) 传⼊要改的个体位置,随机产⽣交叉位置,⽤优良⽗母繁殖优良后代并替代传⼊个体位置5) mutation(i) i为基因组基因的位置,逐个基因看是否要变异6) generation() 对个体进⾏判断,若不符合要求,进⾏选择,重组,突变。

基于遗传算法求解背包问题【精品毕业设计】(完整版)

基于遗传算法求解背包问题【精品毕业设计】(完整版)

毕业设计(论文)基于遗传算法求解背包问题院别专业名称班级学号学生姓名指导教师2012年6月15日基于遗传算法求解背包问题摘要背包问题(Knapsack problem)是一种组合优化的NP完全问题,本文首先介绍了基本遗传算法的基本原理、特点及其基本实现技术,接着针对背包问题,论述了遗传算法在编码表示和遗传算子(包括选择算子、交叉算子变异算子这三种算子)等方面的应用情况。

并且结合背包问题实例,给出了具体的编码方法,运行参数,群体大小,最大迭代次数,以及合适的遗传算子。

最后,简单说明了遗传算法在求解背包问题中的应用并对遗传算法解决背包问题的前景提出了展望。

关键词:背包问题,遗传算法,遗传算子Genetic Algorithm for KPAuthor:Yang DongTutor:Kong ZhiAbstractKP (Knapsack Problem) is a combinatorial optimization of NP - complete problem. The primary knowledge, characteristics and the basic techniques of GA are introduced firstly. The encoding model and genetic operators (including selection operation, crossover operation and mutation operation) solving KP are discussed secondly. Combined with examples of knapsack problem, we have given the specific encoding method, operating parameters, popsize, maxgeneration, and suitable genetic operator. At last, the application of genetic algorithm is simple presented, and the prospect for the future of genetic algorithm in solving KP has been given.Key Words: KP, genetic algorithm, genetic operators目录1绪论 (III)1.1 引言 (1)1.2 背包问题概述 (1)1.2.1 背包问题的描述 (2)1.2.2 研究背包问题的意义 (9)1.3 遗传算法 (10)1.3.1 遗传算法概述 (10)1.3.2 遗传算法的特点 (10)1.3.3 遗传算法的应用领域 (11)2遗传算法的基本原理 (13)2.1 基本流程 (14)2.2 编码 (14)2.3 适应度函数 (15)2.4 遗传算子 (15)2.4.1 选择算子 (15)2.4.2 交叉算子 (17)2.4.3 变异算子 (17)2.5 参数控制 (18)2.5.1 群体规模 (18)2.5.2 交叉概率 (18)2.5.3 变异概率 (18)2.6 算法结束条件控制 (19)3求解实现背包问题的遗传算法 (20)3.1 0_1背包问题中染色体的表示 (20)3.2 算法求解01背包问题时用到的参数 (20)3.3 选择操作 (20)3.4 交叉操作 (21)3.5 精英策略 (22)3.6 变异操作 (22)3.7 代际更新 (23)3.8 算法的终止 (23)3.9 仿真结果与测试 (24)3.9.1 不同交叉概率下所的测试结果 (25)3.9.2 极端数据对结果的影响 (27)3.9.3 仿真结果总结 (29)结论 (31)致谢 (32)参考文献 (33)附录 (34)1绪论1.1引言现代科学理论研究与实践中存在着大量与优化、自适应相关的问题,但除了一些简单的情况之外,人们对于大型复杂系统的优化和自适应问题仍然无能为力。

matlab、lingo程序代码3-背包问题(遗传算法)

matlab、lingo程序代码3-背包问题(遗传算法)

背包问题——-遗传算法解决function Population1=GA_copy(Population,p,w0,w)%复制算子%Population为种群n=length(Population(:,1));fvalue=zeros(1,n);for i=1:nfvalue(i)=GA_beibao_fitnessvalue(Population(i,:),p,w0,w); endfval=fvalue/sum(fvalue);F(1)=0;for j=1:nF(j+1)=0;for k=1:jF(j+1)=F(j+1)+fval(k);endendfor i=1:ntest=rand;for j=1:nif((test〉=F(j))&&(test〈F(j+1)))Population1(i,:)=Population(j,:);endendendfunction Population1=GA_exchange(Population,pc)%遗传算法交换算子%pc为交换概率Population1=Population;POP=[];n=length(Population(:,1));%k=floor(n*pc);%用于交换的染色体数目%采用单点交换算子j=1;l=length(Population(1,:));for i=1:ntest(i)=rand;if test(i)〈pcfor z=1:lPOP(j,z)=Population(i,z);endPOP(j,l+1)=i;p(j)=randint(1,1,[1 l—1]);j=j+1;endendk0=j-1;k=floor(k0/2);if k〉=1for m=1:kfor t=p(2*m-1)+1:ls=POP(2*m—1,t);POP(2*m—1,t)=POP(2*m,t);POP(2*m,t)=s;endendfor m=1:k0for i=1:lPopulation1(POP(m,l+1),i)=POP(m,i);endendendfunction fitnessvalue=GA_fitnessvalue(x,p,w0,w)%使用惩罚法计算适应度值%x为染色体%p为背包问题中每个被选物体的价值%w0为背包问题中背包总容积%w为背包问题中每个被选物品的容积l=length(x);for i=1:la(i)=p(i)。

基于遗传算法解决01背包问题研究

基于遗传算法解决01背包问题研究
背包 , 则O 1背 包 问题 的数 学模 型 为 ma x f ( x , 。 … … ,
) 一> : P ( i 一1 , 2 , 3 ……, ) , n 个物体的背包问题的
i— l
v e c t o r <i n t > &b a b y l , v e c t o r <i n t >  ̄b a b y 2 ){
个 体 的 同 时 比较 , 搜 索 使 用 评 价 函数 启 发 , 过 程 简单 , 使 用 概 率机 制 进 行 迭 代 , 具 有随机 性, 具 有 可 扩展 性 , 容 易 与 其 它 算 法 结合 。基 本 0 1背 包 问题 , 提 出遗 传 问 题 解 决 的 关键 技 术 , 设 计 评 价 函数 和 遗 传 算 子 , 并通过散播 变异 、 移 位 变 异、 插入 变异 改 进 0 l背 包 问题 中 的 遗 传 算 法 , 很 好 地 解 决 了遗传 问题 。
关键词 : 遗传算 法; 0 1背 包 I " - I 题; 评价函数 ; 遗传 算子
中 图分 类号 : TP 3 1 2
文献标识码 : A
文章编号 : 1 6 7 2 - 7 8 0 0 ( 2 0 1 4 ) 0 0 2 - 0 0 7 4 - 0 2
i n t S e l e c t e d Ge n o me一 0 :


i nt c p — Ra nd l nt ( 0,m i Ch r o mo Le n g t h一 1 ) ;

f o r( i n t i 一 0;i <c p;+ + i ) {

2 . 2 用 遗 传 算 子 改 变 繁 殖 过 程 中 产 生 的 子 个 体 遗 传 组 成

利用遗传贪婪混合算法求解背包问题

利用遗传贪婪混合算法求解背包问题
ha t e c nve ge e pe f m a e T he e e i e a r s t s w he be t r pe f m a c he i — s be t r o r nc r or nc . xp rm nt l e uls ho t te r or n e of t m
式 中 : O 决 策变 量 , z 为 一1 z 一1时表示 将物 品 i 装
Co ue mp tr& I fr t n E gn eig,Ha bnUnv riyo mme c , r i 5 0 0,Chn ) n o mai n ie rn o r i ie st fC o re Habn 1 0 0 ia
Ab ta t K n p a k p o lm s s l e y t e h b i e e i a d g e d l o ih . e p o o e t o sr c : a s c r b e i o v d b h y rd g n t n r e y a g rt m W r p s d a me h d c t a s u e o s l e p e a u e c n e g n e wi p r t r c mp n a i n Th t o s a l o o e c me h ti s d t o v r m t r o v r e c t o e a o o e s to . h e me h d i b e t v r o
具 有 更 好 的 收敛 性 能 。实 验 结 果 表 明 , 算 法 性 能 较 佳 , 以 满 足 解 决 背 包 问题 的需 要 。 该 可 关 键 词 : 包 问 题 ; 传 算 法 ; 婪 算 法 ; 熟 收 敛 背 遗 贪 早
中 图分 类 号 : P 0 . T 316 文献标志码 : A 文 章 编 号 :6 14 7 (0 0 0 —0 30 1 7 —6 92 1 )40 4 —3
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.3取 ,其中 表示0-1整数的均匀分布函数,即随机地生成数0或1,生成的 串即可看为一个染色体个体。
若不满足模型(*)的约束条件,则拒绝接受,由1.2重新生成一个新的染色体个体chrom;如果产生的染色体可行,则接受它作为种群的一名成员,经过有限次的1.2抽样后,得到popsize个可行的染色体chrom,形成新的种群。
6.3 种群的代数gen=genm+1,若gen〉Maxgen,则结束种群的演化,否则转到步骤2。
六、遗传算法求解的实现
1、遗传算法的主要参数
#define popsize 80 //种群的规模
#define pc 0.7 //杂交概率
#define pm 0.1 //变异概率
#define lchrom 50 //染色体长度
返回值:无;
流程图:见图ቤተ መጻሕፍቲ ባይዱ。
图4、函数statistics的流程图
图5、函数report的流程图
(5)、void initpop( )
功能:生成初始种群;
参数:无;
返回值:无;
流程图:见图6。
图6、函数initpop流程图
(6)、int execise(double probability)
功能:概率选择试验,以概率probability做随机试验,判断是否进行交叉或变异操作;
#define maxgen 5000 //最大进化代数
double alpha;//计算适应度时使用的 惩罚函数系数
2、数据结构
(1)背包信息:
//背包问题中物体重量、收益、背包容量
int weight[lchrom],profit[lchrom],contain;
(2)种群个体结构体
struct population
使用递归回溯法解决背包问题的优点在于它算法思想简单,而且它能完全遍历搜索空间,肯定能找到问题的最优解;但是由于此问题解的总组合数有 个,因此,随着物件数n的增大,其解的空间将以 级增长,当n大到一定程度上,用此算法解决背包问题将是不现实的。
使用贪心方法求解时计算的复杂度降低了很多,但是往往难以得到最优解,有时所得解与最优解相差甚远。因此,我们可以探索使用遗传算法解决物件数较大的背包问题。
遗传算法是将问题的每一个可能性解看作是群体中的一个个体(染色体),并将每一个染色体编码成串的形式,再根据预定的目标函数对每个个体进行评价,给出一个适应值。算法将根据适应度值进行它的寻优过程,遗传算法的寻优过程是通过选择、杂交和变异三个遗传算子来具体实现的。它的搜索能力由选择算子和杂交算子决定,变异算子则保证了算法能够搜索到问题空间的尽可能多的点,从而使其具有搜索全局最优的能力。遗传算法的高效性和强壮性可由Holland提出的模式定理( Schema Therem)和隐式并行性得以解释。在遗传算法中,定义长度较短、低阶且适应值超过平均适应值的模式在群体中数目的期望值按指数递增,这个结论称为遗传算法的基本定理。遗传算法是通过定义长度短、确定位数少、适应度值高的模式的反复抽样、组合来寻找最佳点,称这些使遗传算法有效工作的模式为积木块,是遗传算法构造答案的基本材料。但归根到底,要使遗传算法有效工作必须按照遗传算法的模式定理(或积木块假设)根据具体问题设计合理的编码方案。
在运行遗传算法程序时,需要对一些参数作事先选择,它们包括种群的大小、染色体长、交叉率、变异率、最大进化代数等,这些参数对GA的性能都有很重要的影响。在试验中参数一般选取如下:种群大小N= 20~100 ,交叉概率 = 0.4 ~0.9 ,变异概率 = 0.001~0.1 ,最大进化代数maxgen = 100~500。
目标函数:
(*)
式中 为0-1决策变量, 时表示将物品 装入背包中, 时则表示不将其装入背包中。
三、求解背包问题的一般方法
解决背包问题一般是采取动态规划、递归回溯法和贪心方法。动态规划可以把困难得多阶段决策变换为一系列相互联系比较容易的单阶段问题。对于背包问题可以对子过程用枚举法求解,而且约束条件越多,决策的搜索范围越小,求解也越容易。它的主要缺点是用数值方法求解时会随着状态变量的个数呈指数级的增长,往往对于求解背包问题的实际问题是不现实的。
(4)适应度信息
//种群的总适应度、最小、最大适应度
doublesumfitness,minfitness,maxfitness;
//一个种群中最大和最小适应度的个体编号
int minpop,maxpop;
3、主要函数说明
(1)、intread_infor()
功能:从文件knapsack.txt中读出背包信息(物体重量、收益、背包容量);
二、问题描述
背包问题(Knapsack Problem)的一般提法是:已知n个物品的重量(weight)及其价值(或收益profit)分别为 和 ,背包的容量(contain)假设设为 ,如何选择哪些物品装入背包可以使得在背包的容量约束限制之内所装物品的价值最大?
该问题的模型可以表示为下述0/1整数规划模型:
遗传算法是具有“生成+检测”的迭代过程的搜索算法。它的基本处理流程如图1所示。
图1、遗传算法的基本流程
遗传算法的基本流程描述如下:
(1)编码:将解空间的解数据进行二进制编码,表达为遗传空间的基因型串(即染色体)结构数据,如将数据9编码为“1001”;
(2)初始化种群:定义整数pop_size作为染色体的个数,并且随机产生pop_size个染色体作为初始种群;
(3)评估种群中个体适应度:评价函数对种群中的每个染色体(chromosome)求得其个体适应度 ;
(4)选择:选择把当前群体中适应度较高的个体按某种规则或者模型遗传到下一代种群中,这里所用的规则是:染色体在种群中被选择的可能性与其个体的适应度的大小成正比;
(5)交叉:定义参数 作为交叉操作的概率,由(4)选择得到的两个个体以概率 交换各自的部分染色体,得到新的两个个体;
遗传算法已经成为组合优化问题的近似最优解的一把钥匙。它是一种模拟生物进化过程的计算模型,作为一种新的全局优化搜索算法,它以其简单、鲁棒性强、适应并行处理以及应用范围广等特点,奠定了作为21世纪关键智能计算的地位。
背包问题是一个典型的组合优化问题,在计算理论中属于NP-完全问题,其计算复杂度为 ,传统上采用动态规划来求解。设w[i]是经营活动 i 所需要的资源消耗,M是所能提供的资源总量,p[i]是人们经营活动i得到的利润或收益,则背包问题就是在资源有限的条件下,追求总的最大收益的资源有效分配问题。
四、遗传算法简介
遗传算法( Genetic Algorithms,GA)是在1975年首次由美国密西根大学的D。J。Holland教授和他的同事们借鉴生物界达尔文的自然选择法则和孟德尔的遗传进化机制基础之上提出的。经过近30年的研究、应用,遗传算法已被广泛地应用于函数优化、机器人系统、神经网络学习过程、模式识别、图象处理、工业优化控制等领域。
流程图:见图3。
图3、函数cal_fit的流程图
(3)、void statistics(struct population *pop)
功能:群体适应度的最大最小值以及其他信息;
参数:struct population *pop是种群指针,根据指针所指向的种群信息统计群体适应度的信息;
返回值:无;
流程图:见图4。
1.4 置种群的代数gen=0;
步骤2、计算种群中个体适应度以及统计种群适应度情况
2.1 按照下列公式计算种群中个体适应度:

公式(2)的下半部分即为适应度的惩罚函数,其中参数 。
2.2 按公式(3)计算种群的总体适应度,
并且按照排序的方法统计出种群中的最大、最小适应度的染色体个体,分别标记为maxpop、minpop;
(6)变异:定义参数 作为变异操作的概率,由(5)得到每个个体中的每个基因值都以概率 进行变异;
(7)演化:经过选择、交叉和变异操作,得到一个新的种群,对上述步骤经过给定的循环次数(maxgen)的种群演化,遗传算法终止。
五、背包问题的遗传算法求解描述
基于背包问题的模型(*),我们设计了针对于背包问题的染色体编码方法:将待求解的各量 表示成长为 的二进制字符串 ,j=1,2, …,n。 表示物体j不放入背包内, …000111代表一个解,它表示将第1、2、3、6、7…n-2,n-1,n号物体放入背包中,其它的物体则不放入。
参数:无;
返回值:返回读取文件信息是否正确;
流程图:见图2。
图2、read_infor( )流程图
(2)double cal_fit(unsigned int *chr)
功能:种群中个体适应度计算;
参数:unsigned int *chr是染色体个体的指针,根据指针所指向的染色体计算个体的适应度;
返回值:染色体个体适应度的大小;
while sum<wheel-pos && i<=popsize
{ i=i+1;
sum=sum+fitness[i]; //fitness为第i个个体的适应度
}
return i-1; //选择了个体i-1
}
3.3 重复两次操作3.1、3.2,生成两个个体作为交叉操作的父代;
步骤四、交叉操作
4.1 根据事先定义好的交叉概率 ,为了确定是否进行交叉操作,则生成[0,1]的随机数pp,若 ,则进行4.2交叉操作,否则将两个父代保留为下一代的两个个体;
根据遗传算法的基本流程,我们确定了求解背包问题的遗传算法:
步骤1、初始化过程
1.1确定种群规模popsize、杂交概率 、变异概率 、染色体长度lchrom及最大进化代数maxgen;
1.2读入背包问题的相关信息,如每个物体的重量weight[j]、每个物体的收益profit[j]和背包的容量contain,其中 ;
相关文档
最新文档