当前位置:首页 » 操作系统 » 遗传算法回溯

遗传算法回溯

发布时间: 2022-12-30 09:27:41

1. 数学建模常用模型有哪些

1、蒙特卡罗算法,该算法又称随机性模拟算法,是通过计算机仿真来解决问题的算法。

2、数据拟合、参数估计、插值等数据处理算法。

3、线性规划、整数规划、多元规划、二次规划等规划类问题。

4、图论算包括最短路、网络流、二分图等算法,涉及到图论的问题用这些方法解决。

5、动态规划、回溯搜索、分治算法、分支定界等计算机算法。

6、最优化理论的三大非经典算法:模拟退火法、神经网络、遗传算法。

7、网格算法和穷举法,这两者都是暴力搜索最优点的算法,在很多竞赛题中有所应用。

8、数值分析算法,比如方程组求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调用。

2. 哪里有0—1背包算法各种方法的总结啊,包括动态规划、贪心、回溯、分支界限等等

我记得以前有一篇180页的pascal算法,我用delphi实现了其中一部分,这些算法都相当有用,但是也是超难,我啃回溯啃了5天。动态规划在分类步骤比较小的情况下用,递归太常用了,回溯就是循环的递归(解决回路嵌套问题),枚举只有情况有限的时候一个个列举出来,贪心就是不求最佳,找一个满足添加的结果就行

3. 基于遗传算法的叠前地震波形反演构建虚拟井曲线

罗文造1杨绍国2王英民3

(1.广州海洋地质调查局 广州 510760;2.成都理工大学 成都 610059;3.中国石油大学(北京)北京 102200)

第一作者简介:罗文造,男,1969年出生,高级工程师,主要从事地球物理技术方法研究。

摘要 叠前地震波形反演能够提供详细的地下地层特征,但由于其计算量大、数据和模型之间的非线性、目标函数的多极值和反演结果的多解性使叠前地震反演的实施成为一大难点。本文通过叠前和叠后混合反演技术采用遗传算法实现了深海无井地震反演。遗传算法思想简单、易于实现和使用、具有隐含并行性和全局搜索能力等优点,基于遗传算法的叠前地震波形反演得到了与井中实际数据基本吻合的速度和密度数据。

关键词 叠前反演 遗传算法 虚拟井

1 前言

地震反演分为叠前反演和叠后反演。一般叠前反演方法所得到的物理特性与叠后反演方法相比提供了更详细的地下地层特征。叠前反演分辨率高,但速度慢、稳定性差,现处于研究阶段,距大规模生产应用还有一定距离。叠后反演虽然分辨率要低一些,但速度快、稳定性好,可满足大规模生产应用的需要。

叠前地震波形反演所面临的难题在于:①计算量和数据量非常庞大;②数据和模型之间高度非线性;③目标函数具有多个极小值;④反演结果具有多解性,可能存在多个模型与地震数据匹配良好(Sen等,1991)。非线性、非唯一性和大计算量交织在一起,使叠前地震波形反演的难度很大。但它对储层岩性和所含流体的高分辨率,对油气勘探开发技术研究人员来说具有较大的吸引力。针对叠前地震波形反演所面临的难题,近十年来,有许多地球物理工作者进行了大量的探索,取得了重要的研究成果,这些进展基本上解决了叠前地震波形反演所面临的高度非线性和局部极小值问题;但对非唯一性和大计算量的问题没得到很好解决。为此,有些学者采用了一种折中的办法,即叠前和叠后混合反演的办法,首先在一些控制点进行精细的叠前地震波形反演构建虚拟井曲线,然后以虚拟井作为控制信息进行叠后反演(Mallick,2000)。叠前和叠后混合反演的办法利用了叠前反演分辨率高,叠后反演速度快、稳定性好的优点,克服了各自的缺点,成为目前的一个研究亮点。特别对于深海无井的情况,具有很好的应用前景。本文采用叠前和叠后混合反演的办法实现深海无井地震反演,其关键是叠前地震波形反演构建虚拟井曲线方法的研究。

2 遗传算法基本原理

遗传算法(Genetic Algorithm,简称GA)是美国Michigan大学的John H.Holland在60年代提出的,目的是把自然界的自适应机理应用于计算机系统的设计。目前,遗传算法作为一种有效的全局寻优自适应概率算法,由于其算法思想简单、易于实现、易于使用、具有隐含并行性和全局搜索能力等优点,且对很多优化问题能够较容易地得到令人满意的解,在自适应控制、组合优化、模式识别、机器学习、人工智能、地球物理反演、管理决策等涉及优化计算问题的领域得到了广泛的应用,且影响越来越大。

尽管遗传算法在解决复杂非线性优化问题中具有独特的优势,但它本身也有局限性,其突出的一个弱点就是收敛性能差,尤其对于多参数、超大解空间的优化问题,其收敛速度有时让人很难接受,这在一定程度上制约了GA的使用和发展(Sen等,1992)。采用GA求解高维、多约束、多目标的优化问题仍是一个没有很好解决的课题,它的进展将会推动GA在许多工程领域的应用。

遗传算法是一种基于自然选择和基因遗传学原理的随机搜索算法,但又不同于一般随机搜索算法。它是通过将待寻优的模型空间的参数进行编码,并用随机选择作为工具来引导搜索过程向着更高效的方向发展,其计算简单、功能强大(Mallick,1995)。具有以下特点:

1)GA是对要寻优参数的编码进行操作,而不是对参数本身;

2)GA是从“群体”(多个初始点)出发开始的并行操作,可以有效地防止搜索过程收敛于局部是优解,是一种全局寻优的方法,且计算速度较快;

3)GA采用目标函数来确定基因遗传的概率,对问题的依赖性较小,适用范围更广;

4)GA的操作均采用随机概率的方式,减少人为干预对结果的影响;

5)GA以随机选择来引导搜索过程,是一种启发式的搜索方法,搜索效率更高;

6)GA适合于大规模复杂问题的优化,如地震反演问题。

遗传算法运算的原理简单,只涉及参数编码的复制和部分编码的交换和变异操作,标准GA只包括选择、交叉和变异三种基本操作:

(1)选择(Selection)/再生(Reproction)

选择是根据群体成员的适应度值fi,对群体成员进行复制的过程。其按照一定的概率选择优秀成员并复制保留下来,体现“适者生存”的自然规律。

选择运算有许多方法,最简单的方法是采用轮盘赌法。该方法根据群体中各成员的适应度,计算适应概率fpi,适应度越大,适应概率越大。

(2)基因交换(Crossover)/重组(Recombination)

基因交换或重组由两步构成,一是匹配,即对再生的群体成员做随机匹配;二是交换匹配成员的基因,即对每对匹配成员,按照随机概率Pc选择随机位置,将两成员的编码进行交换或重组。经过再生所得的新群体中并没有新成员,也就是在搜索空间中没有得到新的搜索点。而按随机概率进行基因交换后,新群体中既有上一代的优秀成员,又有由优秀成员交叉后产生的新成员,得到的新搜索点。根据生物遗传的“杂交优势”规律,这种新成员应该优于原成员。

(3)基因变异(mutation)

基因变异的目的是在搜索过程中,不断引入新的信息量,以免再生和交换的遗传过程中丢失潜在的有用遗传物质。基因变异实际上是对群体成员的基因按小概率Pm扰动而使其发生变化,以补充新的信息。

遗传算法求解优化问题的基本思路:

(1)确定目标函数

目标函数(Objects)是刻画最优解的标准,也是适度计算的依据。一般是以计算值与观测值之间的拟合程度或误差大小为标准的。

(2)指定问题参数的搜索范围

给定每一个模型参数的取值范围,对任一参数x给出[Xmin,Xmax)。实际上是问题解空间搜索精度的描述,其决定了搜索空间的大小,精度越高,离散化的搜索空间越大。

(3)模型参数编码

由于GA运算是对模型参数的编码进行的。编码方式有多种,常用的有二进制编码和十进制编码。

(4)初始群体的产生

给定群体成员数n,用随机生成的方法获取n个群体成员构成初始群体;

(5)遗传计算

① 求取适应度值

适应度值是直接由目标函数转换计算出来的。对最小化问题可用

指数转换:

南海地质研究.2006

i=1,…,n

其中:Objects[i]为第i个成员的目标函数值;σ为群体目标函数值的方差;Fitness[i]为第i个成员的适应度值。

② 再生

计算再生概率:

南海地质研究.2006

Ps[0]=0;

南海地质研究.2006

i=1,…,n

生成[0,1]随机数r,如果Ps[i-1]≤r<Ps[i]则第i个成员获得再生。

③ 交叉

将群体成员两两配对,组成n/2对母本,并按概率Pc进行交叉;即产生[0,1]随机数r,如果r<=Pc,则在一随机位置交换两个母本的编码;否则不变。

④ 变异

对每一个新成员,按概率Pm进行基因的随机突变,即产生[0,1]随机数r,如果r<=Pm,则在一随机位置改变该成员的编码,由1变0,或由0变1。

遗传算法对问题的求解是通过对寻优参数空间进行编码,从多点出发,采用随机选择作为工具来引导搜索过程向着更高效的方向发展,是一种普适性的搜索方法(Mallick,1999)。由于在搜索过程中使用了其父辈的适应度函数值作为启发知识,因此又是一种启发式搜索方法。这种搜索方法,对于简单的多极值优化问题可能会产生好的效果。尽管如此,GA对于多参数复杂非线性问题收敛速度还是过慢(Xia等,1998)。

就遗传算法本身而言,提高其收敛速度的关键在于合理的适合问题特点的遗传编码方法、适应度函数及变换方法、遗传算子、算法参数的设置和选取。

3 基于遗传算法的叠前地震波形反演

采用GA叠前地震波形反演估算弹性参数。叠前反演在角道集上进行,以便减少计算工作量。叠前资料预处理包括:角道集抽取、叠前去噪、压制多次波和高精度速度分析等方。GA叠前地震波形反演的技术路线如图1。

图1 GA叠前地震波形反演框图

Fig.1 The flow chart of pre-stack seismic waveform inversion by means of GA

其算法如下:

1)准备初始模型、地震记录Seis等数据

由高精度速度分析构建初始模型,地震记录Seis为角道集地震记录。

2)确定地质模型参数及参数搜索范围和搜索间隔

3)对模型参数编码。根据搜索范围的搜索间隔,先确定各参数可能取得的不同值的个数,为节省空间对所有参数进行整数编码。

4)生成拟合模型的初始随机总体P,假设生成了n个随机模型

由X=Xmin+Code×Dx,对Vp,Vs和ρ三个参数nt个样点用随机生成的方式生成整数码产生要求的样本量。

5)计算各模型的合成地震记录Syni。

合成地震记录采用Zoeppritz方程计算。

6)比较Syni与Seis,计算并保存目标函数值

观测记录与合成记录之间的匹配程度称为模型的拟合度(Inger等,1992),如果随机模型与实际情况相差很远,由观测记录计算得到的角道集与相应的合成角道集匹配就会很差。相反如果所选随机模型接近实际情况,从而使由观测记录计算得到的角道集与相应的合成角道集能很好地匹配。

南海地质研究.2006

i=1,…,n

其中:n为群体样本数;从理论上说,点越多,搜索效率应该越高。但实际上增加搜索点,也高增加了遗传计算的计算量。因此解决实际问题时,根据问题的性质及解空间的大小,做适当选择。在计算时,由于遗传计算量相对较大,选择了较小的群体。为便于操作和增加程序的适应能力,采用人机交互输入的方式选择8到32间的偶整数。

Nt=nt×angles;

nt:地震道时间取样点数;

angles:角道集所选角度个数。

seis[j]:观测记录角道集

Syn[j][i]:第i个群体成员的合成记录角道集

7)根据目标函数值对P做再生、交叉、变异操作,更新P生成新的随机总体;

8)如果满足结束条件,结束并输出结果;否则重复5)至8)直到结束。

4 叠前地震波形反演的实施

针对地震波反演问题这种多参数、复杂非线性问题的特点采用了如下技术措施:

(1)编码方法

对多参数、复杂非线性问题,其编码的优劣直接影响计算效率。为此采用了整数编码方案有效降低码的长度,加快计算速度。参数编码采用整数编码,方法如下:

参数值=参数最小值+码值×参数搜索精度;

码值=(参数值-参数最小值)/参数搜索精度;

即:Dx=(Xmax-Xmin)/Codemax

X=Xmin+Code×Dx

Code=(X-Xmin)/Dx

(2)适应度函数

适应度函数是由目标函数转换而得的用以刻划个体适应生存能力的函数。对极小值问题一般采用指数变换,但这种变换是一种均匀变换,在计算后期当群体中各样本目标函数值接近时,为增加优秀个体在再生时被选中的可能性,从而加快算法收敛,选择采用了S函数做叠加变换。

开始时使用指数变换:

南海地质研究.2006

i=1,…,n

其中:Objects[i]为第i个成员的目标函数值;σ为群体目标函数值的方差;Fitness[i]为第i个成员的适应度值。

当群体中样本目标函数值接近时使用S函数变换:

南海地质研究.2006

用于在遗传迭代计算后期,当群体各样本适应度很接近时,以指数形式放大平均适应度以上的样本适应度差异,缩小平均适应度以下的样本适应度的差异,以便更好地选择优秀个体(Sen,2001)。

式中:x对应用不同样本的原适应度值;y为变换后的适应度值;θ0为所有样本的平均适应度。a>0表示用于控制放大比例参数,越大对平均值以上的部分放大越明显。b>0表示调节系数,当a=1时,可取b为8到10;b太大达不到对接近最大值处的适应度的放大,b较小时可用线性变换取代。

南海地质研究.2006

当然为达到上述目的,也可使用其它函数,选择使用S函数,一是因为S变换的连续性,可使大于平均值的适应度放大,而使小于平均值的适应度缩小。二是基于前人的经验增加优秀个体在再生时被选中的可能性,从而加快算法收敛。

(3)算法过程

一般GA在计算时采用的是上一代的适应度作为启发函数再生后进行的随机启发搜索方法。为提高算法速度在实际处理中除使用上一代的适应度,还充分利用了优秀的隔代遗传的信息作为启发信息,参与遗传过程的计算。采用一种有限深度回溯搜索的方法,避免了迭代计算的反复,从而加快了计算收敛速度。事实上,在超大解空间中,某一代的遗传性能往往很难决定最终结果的好坏。另外,在交叉中每对成员交叉变换使用两次概率选择方法,即先选成员对,再选参数,且每个参数分别选择,这样可以有效地增加搜索能力。

5 试算效果实例分析

图2给出了理论地震记录的基于遗传算法的叠前地震波形反演的实例。图中展示了反演纵波速度和实际井中速度曲线,反演横波速度和实际井中速度曲线,反演密度和实际井中密度曲线,理论地震角道集记录和反演结果的合成角道集记录。基于遗传算法叠前反演结果与井中实际数据基本吻合,理论地震角道集记录和反演结果的合成角道集记录吻合非常好。

图2 基于遗传算法的叠前地震波形反演实例

Fig.2 A case for GA based pre-stack seismic waveform inversion

图中从左到右为反演纵波速度和实际井中速度曲线,反演横波速度和实际井中速度曲线,反演密度和实际井中密度曲线,5°理论地震角道集记录和反演结果的合成角道集记录,10°理论地震角道集记录和反演结果的合成角道集记录,15°理论地震角道集记录和反演结果的合成角道集记录,20°理论地震角道集记录和反演结果的合成角道集记录

参考文献

Inger L,and Rosen B.1992.Genetic algorithms and very fast simulated annealing:A comparision,Math.Comput.Modelling,16,87~100

Mallick S.1995.Model-based inversion of amplitude-variation-with-offset data using a genetic algorithm,Geophysics,52,1355~1364

Mallick S.1999.Some practical aspects of prestack waveform inversion using a genetic algorthm:An example from the east Texas Woodbine gas sand,Geophysics,64,326~336

Mallick S.2000.Hybrid seismic inversion:A reconnaissance tool for deepwater exploration.The Leading Edge,19,1230~1237

Sen M K,and Stoffa P L.1991.Nonlinear one-dimensional seismic waveform inversion using simulated annealing,Geophysics,56,1624~1638

Sen M K,and Stoffa P L.1992.Rapid sampling of model space using genetic algorithms:Examples from seismic waveform inversion,Geophys.J.Internat.,108,281~292

Sen M K.2001.Pre-stack waveform inversion:Current status and future direction,Institute for Geophysics

Xia G,Sen M K,and Stoffa P L.1998.1-D elastic waveform inversion:A divide-and-conquer approach,Geophysics,63,1670~1684

The construction of pseudo-well logs by inversion of pre-stack seismic waveform based on genetic algorithm

Luo Wenzao1Yang Shaoguo2Wang Yingmin3

(1.Guangzhou Marine Geological Survey,Guangzhou,510760;2.Cheng University Sciences and Technologies,Cheng,610059;3.China Petroleum University,Beijing,102200)

Abstract:The inversion of pre-stack seismic waveform is capable of providing the detailed character of subsurface stratigraphy.But its large scale of calculation,the non-linear relationship between data and model,multi-pole of objective functions and its multi-resolution has resulted in the difficulty of its operation.The seismic inversion without well constrained in the deep sea has been realized by hybrid inversion of pre-and post-inversion.The genetic algorithm is simple,easy to realizing and using with the character of latent paralleling and global searching capability.The inversion of pre-stack seismic waveform based on genetic algorithm gives the velocity and density which consists basically with those from the wells.

Key Words:Pre-stack inversion Genetic algorithm Pseudo-well

4. 数学建模需要掌握哪些编程语言和技术

数学建模需要掌握MATLAB、Python、SAS、Lingo等编程语言。

5. 数学建模的应用范围有多大

例如给你一些数据让你分析一个城市的经济发展水平,或者给出数据让你选择有价证券,亦或分析垄断行业的价格与服务。需要用到数据统计模型和优化模型。不会涉及很深的专业知识,也不必刻意去了解多少经济方面的知识,要知道中国数学建模大赛是全国各高校各专业学生皆可参加的竞赛。你只要了解并且能够熟练运用数学建模的几种基本模型就可以(建模时也就用这几种模型,就算过多的运用专业知识也未必得高分,因为这个竞赛比的是把实际问题抽象成数学问题的能力,而非专业技巧)。
这几种基本模型有:优化模型、微分方程模型、统计模型、概率模型、图论模型、决策模型。
在这几种模型中贯穿着以下几种算法(下面我就复制粘贴了):
1、蒙特卡罗算法(该算法又称随机性模拟算法,是通过计算机仿真来解决问题的算
法,同时可以通过模拟可以来检验自己模型的正确性,是比赛时必用的方法)

2、数据拟合、参数估计、插值等数据处理算法(比赛中通常会遇到大量的数据需要
处理,而处理数据的关键就在于这些算法,通常使用Matlab作为工具)

3、线性规划、整数规划、多元规划、二次规划等规划类问题(建模竞赛大多数问题
属于最优化问题,很多时候这些问题可以用数学规划算法来描述,通常使用Lindo、
Lingo软件实现)

4、图论算法(这类算法可以分为很多种,包括最短路、网络流、二分图等算法,涉
及到图论的问题可以用这些方法解决,需要认真准备)

5、动态规划、回溯搜索、分治算法、分支定界等计算机算法(这些算法是算法设计
中比较常用的方法,很多场合可以用到竞赛中)

6、最优化理论的三大非经典算法:模拟退火法、神经网络、遗传算法(这些问题是
用来解决一些较困难的最优化问题的算法,对于有些问题非常有帮助,但是算法的实
现比较困难,需慎重使用)
7、网格算法和穷举法(网格算法和穷举法都是暴力搜索最优点的算法,在很多竞赛
题中有应用,当重点讨论模型本身而轻视算法的时候,可以使用这种暴力方案,最好
使用一些高级语言作为编程工具)
8、一些连续离散化方法(很多问题都是实际来的,数据可以是连续的,而计算机只
认的是离散的数据,因此将其离散化后进行差分代替微分、求和代替积分等思想是非
常重要的)
9、数值分析算法(如果在比赛中采用高级语言进行编程的话,那一些数值分析中常
用的算法比如方程组求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调
用)
10、图象处理算法(赛题中有一类问题与图形有关,即使与图形无关,论文中也应该
要不乏图片的,这些图形如何展示以及如何处理就是需要解决的问题,通常使用Matlab
进行处理)

我今年9月份要参加数学建模,希望和你相互交流,共同进步!

6. cet-4网考模拟系统怎么用

进真题演练,服务器地址写211.161.1.5,先注册个号再进入,是模拟的,所以不一定打真实信息,但要记住用户名和密码啊···

1 自动组卷算法比较

实现自动组卷是CET-4在线模拟考试系统的核心。随机抽取法和回溯试探法是过去经常被使用的自动组卷算法,但都存在着严重的不足。随机抽取法具有很大的随意性和不确定性。回溯试探法虽然组卷成功率远远高于随机抽取法,但其组卷效率并不高。遗传算法是在结合以上两种算法基础上所得到的一种新的改进算法,它是一种并行的、能够有效优化的算法[1],具有简单通用、鲁棒性强、全局寻优、收敛速度快等特点。

2 遗传算法的基本步骤

遗传算法的基本步骤主要包括编码、初始化群体、适应度计算、选择、交叉和变异。

3 基于遗传算法组卷的关键技术

将遗传算法应用于组卷,关键技术就在于遗传算法的基本步骤在组卷中的实现。

3.1 编码方案

7. 线性算法是指什么样算法请举几个例子。类似于进化算法就是指遗传算法,人工免疫算法等。

这里说的线性算法应该是从时间复杂度方面来说的,相对于进化算法的话。
即在线性时间或 Ο(n)时间内能求得问题最优解的算法,统称为线性算法。比如说动态规划法、分治法、回溯法、递归法等。
供参考

8. 遗传算法,回溯算法,贪心算法以及动态规划是什么通俗点

回溯就是不断的尝试各种可能,贪心就是一直往下走,拿最优的,答案不一定就是全局最优。动态规划就是枚举最优的子状态得到当前状态...具有阶段性,答案保证是全局最优的。但用空间换时间

9. 遗传算法求解背包问题的程序

1楼的不是遗传算法吧!
刚好做过这个遗传算法解背包问题的论文,给你回答啦~~独家哦,分数要给偶~~

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 <AfxWin.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <stdio.h>

// 重要常量参数
#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<lchrom;j++)
{
fscanf(fp,"%d",&profit[j]);
}
//读入物体重量信息
for (j=0;j<lchrom;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<lchrom;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<lchrom;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<popsize;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)
{
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<lchrom;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<popsize;i++)
{
while (!ispop)
{
for(j=0;j<lchrom;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<wheel_pos && parent<popsize);
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<popsize)
{
ispop=false;
while (!ispop)
{
//选择
mate1=selection(i);
mate2=selection(i+1);

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

//变异
for (j=0;j<lchrom;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<maxgen)
{
gen=gen+1;
if (gen%100==0)
{
srand( (unsigned)time( NULL ) );//置随机种子
}
oldmax=maxfitness;
oldmaxpop=maxpop;
generation();
statistics(newpop); //统计新生代种群信息
//如果新生代种群中个体的最大适应度小于老一代种群
//个体的最大适应度,则保存老一代种群个体的最大适应度
//否则报告新生代的最大适应度
if (maxfitness<oldmax)
{
for(k=0;k<lchrom;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();
}

热点内容
python字符串存在 发布:2025-05-10 18:14:39 浏览:872
算法示意图 发布:2025-05-10 18:12:54 浏览:987
c语言运算优先级表 发布:2025-05-10 18:09:51 浏览:695
林肯ftp 发布:2025-05-10 18:04:02 浏览:442
自动认购源码 发布:2025-05-10 17:59:08 浏览:917
存储行业发展 发布:2025-05-10 17:56:59 浏览:643
非易失存储技术 发布:2025-05-10 17:47:17 浏览:705
androidstudiosvn 发布:2025-05-10 17:47:14 浏览:112
php下载csv 发布:2025-05-10 17:46:30 浏览:407
为什么每次登录淘宝都要输密码 发布:2025-05-10 17:44:57 浏览:574