当前位置:首页 » 操作系统 » 简单的遗传算法

简单的遗传算法

发布时间: 2022-04-03 20:10:39

python有没有简单的遗传算法

首先遗传算法是一种优化算法,通过模拟基因的优胜劣汰,进行计算(具体的算法思路什么的就不赘述了)。大致过程分为初始化编码、个体评价、选择,交叉,变异。

以目标式子 y = 10 * sin(5x) + 7 * cos(4x)为例,计算其最大值

首先是初始化,包括具体要计算的式子、种群数量、染色体长度、交配概率、变异概率等。并且要对基因序列进行初始化

[python]view plain

  • pop_size=500#种群数量

  • max_value=10#基因中允许出现的最大值

  • chrom_length=10#染色体长度

  • pc=0.6#交配概率

  • pm=0.01#变异概率

  • results=[[]]#存储每一代的最优解,N个二元组

  • fit_value=[]#个体适应度

  • fit_mean=[]#平均适应度

  • pop=geneEncoding(pop_size,chrom_length)


  • 其中genEncodeing是自定义的一个简单随机生成序列的函数,具体实现如下

    [python]view plain

  • defgeneEncoding(pop_size,chrom_length):

  • pop=[[]]

  • foriinrange(pop_size):

  • temp=[]

  • forjinrange(chrom_length):

  • temp.append(random.randint(0,1))

  • pop.append(temp)

  • returnpop[1:]

  • 编码完成之后就是要进行个体评价,个体评价主要是计算各个编码出来的list的值以及对应带入目标式子的值。其实编码出来的就是一堆2进制list。这些2进制list每个都代表了一个数。其值的计算方式为转换为10进制,然后除以2的序列长度次方减一,也就是全一list的十进制减一。根据这个规则就能计算出所有list的值和带入要计算式子中的值,代码如下

    [python]view plain

  • #0.0coding:utf-80.0

  • #解码并计算值

  • importmath

  • defdecodechrom(pop,chrom_length):

  • temp=[]

  • foriinrange(len(pop)):

  • t=0

  • forjinrange(chrom_length):

  • t+=pop[i][j]*(math.pow(2,j))

  • temp.append(t)

  • returntemp

  • defcalobjValue(pop,chrom_length,max_value):

  • temp1=[]

  • obj_value=[]

  • temp1=decodechrom(pop,chrom_length)

  • foriinrange(len(temp1)):

  • x=temp1[i]*max_value/(math.pow(2,chrom_length)-1)

  • obj_value.append(10*math.sin(5*x)+7*math.cos(4*x))

  • returnobj_value

  • 有了具体的值和对应的基因序列,然后进行一次淘汰,目的是淘汰掉一些不可能的坏值。这里由于是计算最大值,于是就淘汰负值就好了

    [python]view plain

  • #0.0coding:utf-80.0

  • #淘汰(去除负值)

  • defcalfitValue(obj_value):

  • fit_value=[]

  • c_min=0

  • foriinrange(len(obj_value)):

  • if(obj_value[i]+c_min>0):

  • temp=c_min+obj_value[i]

  • else:

  • temp=0.0

  • fit_value.append(temp)

  • returnfit_value


  • 然后就是进行选择,这是整个遗传算法最核心的部分。选择实际上模拟生物遗传进化的优胜劣汰,让优秀的个体尽可能存活,让差的个体尽可能的淘汰。个体的好坏是取决于个体适应度。个体适应度越高,越容易被留下,个体适应度越低越容易被淘汰。具体的代码如下

    [python]view plain

  • #0.0coding:utf-80.0

  • #选择

  • importrandom

  • defsum(fit_value):

  • total=0

  • foriinrange(len(fit_value)):

  • total+=fit_value[i]

  • returntotal

  • defcumsum(fit_value):

  • foriinrange(len(fit_value)-2,-1,-1):

  • t=0

  • j=0

  • while(j<=i):

  • t+=fit_value[j]

  • j+=1

  • fit_value[i]=t

  • fit_value[len(fit_value)-1]=1

  • defselection(pop,fit_value):

  • newfit_value=[]

  • #适应度总和

  • total_fit=sum(fit_value)

  • foriinrange(len(fit_value)):

  • newfit_value.append(fit_value[i]/total_fit)

  • #计算累计概率

  • cumsum(newfit_value)

  • ms=[]

  • pop_len=len(pop)

  • foriinrange(pop_len):

  • ms.append(random.random())

  • ms.sort()

  • fitin=0

  • newin=0

  • newpop=pop

  • #转轮盘选择法

  • whilenewin<pop_len:

  • if(ms[newin]<newfit_value[fitin]):

  • newpop[newin]=pop[fitin]

  • newin=newin+1

  • else:

  • fitin=fitin+1

  • pop=newpop

  • 以上代码主要进行了3个操作,首先是计算个体适应度总和,然后在计算各自的累积适应度。这两步都好理解,主要是第三步,转轮盘选择法。这一步首先是生成基因总数个0-1的小数,然后分别和各个基因的累积个体适应度进行比较。如果累积个体适应度大于随机数则进行保留,否则就淘汰。这一块的核心思想在于:一个基因的个体适应度越高,他所占据的累计适应度空隙就越大,也就是说他越容易被保留下来。
  • 选择完后就是进行交配和变异,这个两个步骤很好理解。就是对基因序列进行改变,只不过改变的方式不一样

    交配:

    [python]view plain

  • #0.0coding:utf-80.0

  • #交配

  • importrandom

  • defcrossover(pop,pc):

  • pop_len=len(pop)

  • foriinrange(pop_len-1):

  • if(random.random()<pc):

  • cpoint=random.randint(0,len(pop[0]))

  • temp1=[]

  • temp2=[]

  • temp1.extend(pop[i][0:cpoint])

  • temp1.extend(pop[i+1][cpoint:len(pop[i])])

  • temp2.extend(pop[i+1][0:cpoint])

  • temp2.extend(pop[i][cpoint:len(pop[i])])

  • pop[i]=temp1

  • pop[i+1]=temp2


  • 变异:
  • [python]view plain

  • #0.0coding:utf-80.0

  • #基因突变

  • importrandom

  • defmutation(pop,pm):

  • px=len(pop)

  • py=len(pop[0])

  • foriinrange(px):

  • if(random.random()<pm):

  • mpoint=random.randint(0,py-1)

  • if(pop[i][mpoint]==1):

  • pop[i][mpoint]=0

  • else:

  • pop[i][mpoint]=1


  • 整个遗传算法的实现完成了,总的调用入口代码如下
  • [python]view plain

  • #0.0coding:utf-80.0

  • importmatplotlib.pyplotasplt

  • importmath

  • fromselectionimportselection

  • fromcrossoverimportcrossover

  • frommutationimportmutation

  • frombestimportbest

  • print'y=10*math.sin(5*x)+7*math.cos(4*x)'

  • #计算2进制序列代表的数值

  • defb2d(b,max_value,chrom_length):

  • t=0

  • forjinrange(len(b)):

  • t+=b[j]*(math.pow(2,j))

  • t=t*max_value/(math.pow(2,chrom_length)-1)

  • returnt

  • pop_size=500#种群数量

  • max_value=10#基因中允许出现的最大值

  • chrom_length=10#染色体长度

  • pc=0.6#交配概率

  • pm=0.01#变异概率

  • results=[[]]#存储每一代的最优解,N个二元组

  • fit_value=[]#个体适应度

  • fit_mean=[]#平均适应度

  • #pop=[[0,1,0,1,0,1,0,1,0,1]foriinrange(pop_size)]

  • pop=geneEncoding(pop_size,chrom_length)

  • foriinrange(pop_size):

  • obj_value=calobjValue(pop,chrom_length,max_value)#个体评价

  • fit_value=calfitValue(obj_value)#淘汰

  • best_indivial,best_fit=best(pop,fit_value)#第一个存储最优的解,第二个存储最优基因

  • results.append([best_fit,b2d(best_indivial,max_value,chrom_length)])

  • selection(pop,fit_value)#新种群复制

  • crossover(pop,pc)#交配

  • mutation(pop,pm)#变异

  • results=results[1:]

  • results.sort()

  • X=[]

  • Y=[]

  • foriinrange(500):

  • X.append(i)

  • t=results[i][0]

  • Y.append(t)

  • plt.plot(X,Y)

  • plt.show()

  • 最后调用了一下matplotlib包,把500代最优解的变化趋势表现出来。
  • 完整代码可以在github查看

    欢迎访问我的个人博客

    阅读全文

② 要一个遗传算法的实现,一个简单的就可以,但是不要太大众的。

留下邮箱吧,我有代码以及解决的问题。

③ 遗传算法 简单程序应用

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

class Best {
public int generations; //最佳适应值代号
public String str; //最佳染色体
public double fitness; //最佳适应值
}

public class SGAFrame extends JFrame {

private JTextArea textArea;
private String str = "";
private Best best = null; //最佳染色体
private String[] ipop = new String[10]; //染色体
private int gernation = 0; //染色体代号
public static final int GENE = 22; //基因数
/**
* Launch the application
* @param args
*/
public static void main(String args[]) {
try {
SGAFrame frame = new SGAFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Create the frame
*/
public SGAFrame() {
super();

this.ipop = inialPops();

getContentPane().setLayout(null);
setBounds(100, 100, 461, 277);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JLabel label = new JLabel();
label.setText("X的区间:");
label.setBounds(23, 10, 88, 15);
getContentPane().add(label);

final JLabel label_1 = new JLabel();
label_1.setText("[-255,255]");
label_1.setBounds(92, 10, 84, 15);
getContentPane().add(label_1);

final JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
SGAFrame s = new SGAFrame();
str = str + s.process() + "\n";
textArea.setText(str);
}
});
button.setText("求最小值");
button.setBounds(323, 27, 99, 23);
getContentPane().add(button);

final JLabel label_2 = new JLabel();
label_2.setText("利用标准遗传算法求解函数f(x)=(x-5)*(x-5)的最小值:");
label_2.setBounds(23, 31, 318, 15);
getContentPane().add(label_2);

final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBounds(23, 65, 399, 164);
getContentPane().add(panel);

final JScrollPane scrollPane = new JScrollPane();
panel.add(scrollPane, BorderLayout.CENTER);

textArea = new JTextArea();
scrollPane.setViewportView(textArea);
//
}

/**
* 初始化一条染色体(用二进制字符串表示)
* @return 一条染色体
*/
private String inialPop() {
String res = "";
for (int i = 0; i < GENE; i++) {
if (Math.random() > 0.5) {
res += "0";
} else {
res += "1";
}
}
return res;
}

/**
* 初始化一组染色体
* @return 染色体组
*/
private String[] inialPops() {
String[] ipop = new String[10];
for (int i = 0; i < 10; i++) {
ipop[i] = inialPop();
}
return ipop;
}

/**
* 将染色体转换成x的值
* @param str 染色体
* @return 染色体的适应值
*/
private double calculatefitnessvalue(String str) {
int b = Integer.parseInt(str, 2);
//String str1 = "" + "/n";
double x = -255 + b * (255 - (-255)) / (Math.pow(2, GENE) - 1);
//System.out.println("X = " + x);
double fitness = -(x - 5) * (x - 5);
//System.out.println("f(x)=" + fitness);
//str1 = str1 + "X=" + x + "/n"
//+ "f(x)=" + "fitness" + "/n";
//textArea.setText(str1);

return fitness;
}

/**
* 计算群体上每个个体的适应度值;
* 按由个体适应度值所决定的某个规则选择将进入下一代的个体;
*/
private void select() {
double evals[] = new double[10]; // 所有染色体适应值
double p[] = new double[10]; // 各染色体选择概率
double q[] = new double[10]; // 累计概率
double F = 0; // 累计适应值总和
for (int i = 0; i < 10; i++) {
evals[i] = calculatefitnessvalue(ipop[i]);
if (best == null) {
best = new Best();
best.fitness = evals[i];
best.generations = 0;
best.str = ipop[i];
} else {
if (evals[i] > best.fitness) // 最好的记录下来
{
best.fitness = evals[i];
best.generations = gernation;
best.str = ipop[i];
}
}
F = F + evals[i]; // 所有染色体适应值总和

}
for (int i = 0; i < 10; i++) {
p[i] = evals[i] / F;
if (i == 0)
q[i] = p[i];
else {
q[i] = q[i - 1] + p[i];
}
}
for (int i = 0; i < 10; i++) {

double r = Math.random();
if (r <= q[0]) {
ipop[i] = ipop[0];

} else {
for (int j = 1; j < 10; j++) {
if (r < q[j]) {
ipop[i] = ipop[j];
break;
}
}
}
}
}

/**
* 交叉操作
* 交叉率为25%,平均为25%的染色体进行交叉
*/
private void cross() {
String temp1, temp2;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.25) {
double r = Math.random();
int pos = (int) (Math.round(r * 1000)) % GENE;
if (pos == 0) {
pos = 1;
}
temp1 = ipop[i].substring(0, pos)
+ ipop[(i + 1) % 10].substring(pos);
temp2 = ipop[(i + 1) % 10].substring(0, pos)
+ ipop[i].substring(pos);
ipop[i] = temp1;
ipop[(i + 1) / 10] = temp2;
}
}
}

/**
* 基因突变操作
* 1%基因变异m*pop_size 共180个基因,为了使每个基因都有相同机会发生变异,
* 需要产生[1--180]上均匀分布的
*/
private void mutation() {
for (int i = 0; i < 4; i++) {
int num = (int) (Math.random() * GENE * 10 + 1);
int chromosomeNum = (int) (num / GENE) + 1; // 染色体号

int mutationNum = num - (chromosomeNum - 1) * GENE; // 基因号
if (mutationNum == 0)
mutationNum = 1;
chromosomeNum = chromosomeNum - 1;
if (chromosomeNum >= 10)
chromosomeNum = 9;
//System.out.println("变异前" + ipop[chromosomeNum]);
String temp;
if (ipop[chromosomeNum].charAt(mutationNum - 1) == '0') {
if (mutationNum == 1) {
temp = "1" + ipop[chromosomeNum].substring

(mutationNum);
} else {
if (mutationNum != GENE) {
temp = ipop[chromosomeNum].substring(0, mutationNum -

1) + "1" + ipop

[chromosomeNum].substring(mutationNum);
} else {
temp = ipop[chromosomeNum].substring(0, mutationNum -
1) + "1";
}
}
} else {
if (mutationNum == 1) {
temp = "0" + ipop[chromosomeNum].substring

(mutationNum);
} else {
if (mutationNum != GENE) {
temp = ipop[chromosomeNum].substring(0, mutationNum -

1) + "0" + ipop

[chromosomeNum].substring(mutationNum);
} else {
temp = ipop[chromosomeNum].substring(0, mutationNum -
1) + "1";
}
}
}
ipop[chromosomeNum] = temp;
//System.out.println("变异后" + ipop[chromosomeNum]);
}
}
/**
* 执行遗传算法
*/
public String process() {
String str = "";
for (int i = 0; i < 10000; i++) {
this.select();
this.cross();
this.mutation();
gernation = i;
}
str = "最小值" + best.fitness + ",第" + best.generations + "个染色体";
return str;
}

}

④ 请问简单遗传算法的时间复杂度和空间复杂度是多少

遗传算法其实就是二重迭代,时间复杂度不超过n平方
空间复杂度自己计算吧

⑤ 简单遗传算法设计问题

是使用而已,matlab里面有自带的GA工具箱

⑥ 遗传算法是怎样诞生的

遗传算法(Genetic
Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法,它最初由美国Michigan大学J.Holland教授于1975年首先提出来的,并出版了颇有影响的专着《Adaptation
in
Natural
and
Artificial
Systems》,GA这个名称才逐渐为人所知,J.Holland教授所提出的GA通常为简单遗传算法(SGA)。

⑦ 遗传算法

遗传算法是从代表问题可能潜在解集的一个种群开始的,而一个种群则由经过基因编码的一定数目的个体组成。每个个体实际上是染色体带有特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因的组合,它决定了个体形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。因此,在一开始需要实现从表现型到基因型的映射即编码工作。由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码。初始种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解。在每一代,根据问题域中个体的适应度(fitness)大小挑选(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。这个过程将导致种群自然进化一样的后生代种群比前代更加适应环境,末代种群中的最优个体经过编码(decoding),可以作为问题近似最优解。

5.4.1 非线性优化与模型编码

假定有一组未知参量

xi(i=1,2,…,M)

构成模型向量m,它的非线性目标函数为Φ(m)。根据先验知识,对每个未知量都有上下界αi及bi,即αi≤x≤bi,同时可用间隔di把它离散化,使

di=(bii)/N (5.4.1)

于是,所有允许的模型m将被限制在集

xii+jdi(j=0,1,…,N) (5.4.2)

之内。

通常目标泛函(如经济学中的成本函数)表示观测函数与某种期望模型的失拟,因此非线性优化问题即为在上述限制的模型中求使Φ(m)极小的模型。对少数要求拟合最佳的问题,求目标函数的极大与失拟函数求极小是一致的。对于地球物理问题,通常要进行杀重离散化。首先,地球模型一般用连续函数表示,反演时要离散化为参数集才能用于计算。有时,也将未知函数展开成已知基函数的集,用其系数作为离散化的参数集xi,第二次离散化的需要是因为每一个未知参数在其变化范围内再次被离散化,以使离散模型空间最终包含着有限个非线性优化可选择的模型,其个数为

地球物理数据处理教程

其中M为未知参数xi的个数。由此式可见,K决定于每个参数离散化的间隔di及其变化范围(αi,bi),在大多数情况下它们只能靠先验知识来选择。

一般而言,优化问题非线性化的程度越高,逐次线性化的方法越不稳定,而对蒙特卡洛法却没有影响,因为此法从有限模型空间中随机地挑选新模型并计算其目标函数 Φ(m)。遗传算法与此不同的是同时计算一组模型(开始时是随机地选择的),然后把它进行二进制编码,并通过繁殖、杂交和变异产生一组新模型进一步有限的模型空间搜索。编码的方法可有多种,下面举最简单的例说明之,对于有符号的地球物理参数反演时的编码方式一般要更复杂些。

假设地球为有三个水平层的层次模型,含层底界面深度hj(j=1,2,3)及层速度vj(j=1,2,3)这两组参数。如某个模型的参数值为(十进制):

h1=6,h2=18,h3=28,单位为10m

v1=6,v2=18,v3=28,单位为 hm/s

按正常的二进制编码法它们可分别用以下字符串表示为:

地球物理数据处理教程

为了减少字节,这种编码方式改变了惯用的单位制,只是按精度要求(深度为10m,波速为hm/s)来规定参数的码值,同时也意味着模型空间离散化间距di都规格化为一个单位(即10m,或hm/s)。当然,在此编码的基础上,还可以写出多种新的编码字符串。例如,三参数值的对应字节顺序重排,就可组成以下新的二进制码串:

地球物理数据处理教程

模型参数的二进制编码是一种数学上的抽象,通过编码把具体的非线性问题和生物演化过程联系了起来,因为这时形成的编码字符串就相当于一组遗传基因的密码。不仅是二进制编码,十进制编码也可直接用于遗传算法。根据生物系统传代过程的规律,这些基因信息将在繁殖中传到下一带,而下一代将按照“适者生存”的原则决定种属的发展和消亡,而优化准则或目标函数就起到了决定“适者生存”的作用,即保留失拟较小的新模型,而放弃失拟大的模型。在传带过程中用编码表示的基因部分地交合和变异,即字符串中的一些子串被保留,有的改变,以使传代的过程向优化的目标演化。总的来说,遗传算法可分为三步:繁殖、杂交和变异。其具体实现过程见图5.8。

图5.8 遗传算法实现过程

5.4.2 遗传算法在地震反演中的应用

以地震走时反演为例,根据最小二乘准则使合成记录与实测数据的拟合差取极小,目标函数可取为

地球物理数据处理教程

式中:Ti,0为观测资料中提取出的地震走时;Ti,s为合成地震或射线追踪算出的地震走时;ΔT为所有合成地震走时的平均值;NA为合成地震数据的个数,它可以少于实测Ti,0的个数,因为在射线追踪时有阴影区存在,不一定能算出合成数据Tj,0。利用射线追踪计算走时的方法很多,参见上一章。对于少数几个波速为常数的水平层,走时反演的参数编码方法可参照上一节介绍的分别对深度和速度编码方法,二进制码的字符串位数1不会太大。要注意的是由深度定出的字符串符合数值由浅到深增大的规律,这一约束条件不应在杂交和传代过程中破坏。这种不等式的约束(h1<h2<h3…)在遗传算法中是容易实现的。

对于波场反演,较方便的做法是将地球介质作等间距的划分。例如,将水平层状介质细分为100个等厚度的水平层。在上地壳可假定波速小于6400 m/s(相当于解空间的硬约束),而波速空间距为100m/s,则可将波速用100m/s为单位,每层用6位二进制字符串表示波速,地层模型总共用600位二进制字符串表示(l=600)。初始模型可随机地选取24~192个,然后通过繁殖杂交与变异。杂交概率在0.5~1.0之间,变异概率小于0.01。目标函数(即失拟方程)在频率域可表示为

地球物理数据处理教程

式中:P0(ωk,vj)为实测地震道的频谱;ωk为角频率;vj为第j层的波速;Ps(ωk,vj)为相应的合成地震道;A(ωk)为地震仪及检波器的频率滤波器,例如,可取

A(ω)=sinC4(ω/ωN) (5.4.6)

式中ωN为Nyquist频率,即ωN=π/Δt,Δt为时间采样率。参数C为振幅拟合因子,它起到合成与观测记录之间幅度上匹配的作用。C的计算常用地震道的包络函数的平均比值。例如,设E[]为波动信号的包络函数,可令

地球物理数据处理教程

式中:tmax为包络极大值的对应时间;J为总层数。包络函数可通过复数道的模拟取得。

用遗传算法作波速反演时失拟最小的模型将一直保存到迭代停止。什么时候停止传代还没有理论上可计算的好办法,一般要显示解空间的搜索范围及局部密度,以此来判断是否可以停止传代。值得指出的是,由(5.4.4)和(5.4.5)式给出的目标函数对于有误差的数据是有问题的,反演的目标不是追求对有误差数据的完美拟合,而是要求出准确而且分辨率最高的解估计。

遗传算法在执行中可能出现两类问题。其一称为“早熟”问题,即在传代之初就随机地选中了比较好的模型,它在传代中起主导作用,而使其后的计算因散不开而白白浪费。通常,增加Q值可以改善这种情况。另一类问题正相反,即传相当多代后仍然找不到一个特别好的解估计,即可能有几百个算出的目标函数值都大同小异。这时,最好修改目标函数的比例因子(即(5.4.5)式的分母),以使繁殖概率Ps的变化范围加大。

对于高维地震模型的反演,由于参数太多,相应的模型字符串太长,目前用遗传算法作反演的计算成本还嫌太高。实际上,为了加快计算,不仅要改进反演技巧和传代的控制技术,而且还要大幅度提高正演计算的速度,避免对遗传算法大量的计算花费在正演合成上。

⑧ 基本的遗传算法

在许多实际应用领域,无论是工程技术科学还是社会经济科学中,都会遇到全局最优化问题[53,56~59,61],这一类问题大多数可以形式化为一个对(S,f)的寻优问题,其中 S⊂R n 是 R n 中的有界集,f∶S→R是 n 维实值函数。所要求解的问题就是要找到一点 x best∈S,使得 f(xbest)是 S 上的全局最优解,可以是极大值或极小值。以极小值为例,即求一点 x min∈S,满足

含水层参数识别方法

尽管人们对这类问题进行了大量的研究,但得到的成绩仍不能令人满意,目前只能解决一些简单的问题。对于更复杂的全局最优化问题,通常是利用数值解法,但许多数值解法都不能找到最优解,只是返回一个接近于全局最优的值。

全局最优化数值方法可以分为两大类:确定性算法和随机算法。在随机算法中,最优化步骤在一定程度上依赖于概率事件,它排除了确定性算法中的一个最大障碍——预先详细说明一个问题的全部特征并针对问题的特征决定算法应采用的对策。与常规的优化算法相比,遗传算法有可能在更大的范围内探寻问题潜在的解。确定性算法没有用到概率信息。只有当对S上进行穷举搜索及对f规定附加的假设条件下,算法才能找到全局最优解。实行穷举搜索在很多情况下(如实数解)是不可能的,因此多采用对f规定附加的假设条件,这必然影响到最终解的可靠性。在这些算法中,搜索速度越快的算法往往意味着需要对f做更多的假设,或者不能保证搜索成功。与此相对照,许多随机算法都可以证明在概率意义下渐近收敛到全局最优解,即这些算法保证以概率1渐近收敛,而且随机算法的计算结果一般要优于那些确定性算法的结果。遗传算法就是其中具有代表性的随机算法。

常用的遗传算法操作有选择(Selection)、交叉(Crossover)、变异(Mutation)。复制是直接将个体的代码进行拷贝形成新个体。下面就选择、交叉与变异操作做一介绍。

7.3.1 选择过程

选择过程是以旋转赌轮Pop-Size次(种群规模,即群体中个体的总个数)为基础,每次旋转都为新的种群选择一个染色体。首先计算出个体i被选择的概率Pi,优秀的染色体其选择概率大,然后根据选择概率的大小将一个圆盘分为Pop-Size个扇形,每个扇形的中心角的大小为2πPi

每次进行选择时,先选择赌轮边界旁一个不动的参考点,赌轮随机地转动,若不动点停留在扇形j内,则选择个体j。个体的适应值越大,被选择的概率越大,从而其染色体被遗传到下一代的概率越大。

赌轮式选择的特点是对于种群内的所有个体,无论其适应值大小,都有被选择的机会。适应值大的个体被选择的概率大,适应值小的个体被选择的概率小。经过选择后适应值大的个体在种群中的数目会增加。这正体现了适者生存的原则。

7.3.2 交叉操作

交叉操作是个有组织的、随机的字符串间的信息交换过程。假设群体G(t)是模式库。历史信息以每个模式实例数目的形式存储于G(t)中。交叉作用产生模式库中已有模式的新的实例,同时也产生新的模式。简单的交叉操作分为三步:

(1)从当前群体G(t)中选择两个个体结构:A=a1a2…an,B=b1b2…bn

(2)以交叉概率 Pc 随机选择一个整数 x∈{1,2,…,n};

(3)交换A和B中位置x右边的元素,产生两个新的个体结构:a1a2…axbx+1…bn和b1b2…bxax+1…an

7.3.3 变异操作

对于群体G(t)中的每个个体A=a1a2…an,简单的变异操作过程如下:

1)每个位置的字符变量都有一个变异概率Pm,各位置互相独立,通过随机过程选择发生变异的位置x1,x2,…,xn

2)产生一个新个体结构 B=a1 a2……an ,其中是从对应位置x 1 的字符变量的值域中随机选择的一个取值。类似地,,…,可以同样得到。

如果每个位置的变异概率等于Pm,那么模式H(阶为o(H))发生一次或多次变异的概率是

含水层参数识别方法

遗传操作除了有选择、交叉、变异等算子外,还有染色体内部复制(Intrachromo-somal plication)、删除、易位(Translocation)、分异(Segregation)等。

⑨ 请问能给几个遗传算法的应用实例么,越简单越好,如果有java程序实现的就太太完美了,

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
* 编写者: 赖志环
* 标准遗传算法求解函数
* 编写日期: 2007-12-2
*/
class Best {
public int generations; //最佳适应值代号
public String str; //最佳染色体
public double fitness; //最佳适应值
}

public class SGAFrame extends JFrame {

private JTextArea textArea;
private String str = "";
private Best best = null; //最佳染色体
private String[] ipop = new String[10]; //染色体
private int gernation = 0; //染色体代号
public static final int GENE = 22; //基因数
/**
* Launch the application
* @param args
*/
public static void main(String args[]) {
try {
SGAFrame frame = new SGAFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Create the frame
*/
public SGAFrame() {
super();

this.ipop = inialPops();

getContentPane().setLayout(null);
setBounds(100, 100, 461, 277);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JLabel label = new JLabel();
label.setText("X的区间:");
label.setBounds(23, 10, 88, 15);
getContentPane().add(label);

final JLabel label_1 = new JLabel();
label_1.setText("[-255,255]");
label_1.setBounds(92, 10, 84, 15);
getContentPane().add(label_1);

final JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
SGAFrame s = new SGAFrame();
str = str + s.process() + "\n";
textArea.setText(str);
}
});
button.setText("求最小值");
button.setBounds(323, 27, 99, 23);
getContentPane().add(button);

final JLabel label_2 = new JLabel();
label_2.setText("利用标准遗传算法求解函数f(x)=(x-5)*(x-5)的最小值:");
label_2.setBounds(23, 31, 318, 15);
getContentPane().add(label_2);

final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBounds(23, 65, 399, 164);
getContentPane().add(panel);

final JScrollPane scrollPane = new JScrollPane();
panel.add(scrollPane, BorderLayout.CENTER);

textArea = new JTextArea();
scrollPane.setViewportView(textArea);
//
}

/**
* 初始化一条染色体(用二进制字符串表示)
* @return 一条染色体
*/
private String inialPop() {
String res = "";
for (int i = 0; i < GENE; i++) {
if (Math.random() > 0.5) {
res += "0";
} else {
res += "1";
}
}
return res;
}

/**
* 初始化一组染色体
* @return 染色体组
*/
private String[] inialPops() {
String[] ipop = new String[10];
for (int i = 0; i < 10; i++) {
ipop[i] = inialPop();
}
return ipop;
}

/**
* 将染色体转换成x的值
* @param str 染色体
* @return 染色体的适应值
*/
private double calculatefitnessvalue(String str) {
int b = Integer.parseInt(str, 2);
//String str1 = "" + "/n";
double x = -255 + b * (255 - (-255)) / (Math.pow(2, GENE) - 1);
//System.out.println("X = " + x);
double fitness = -(x - 5) * (x - 5);
//System.out.println("f(x)=" + fitness);
//str1 = str1 + "X=" + x + "/n"
//+ "f(x)=" + "fitness" + "/n";
//textArea.setText(str1);

return fitness;
}

/**
* 计算群体上每个个体的适应度值;
* 按由个体适应度值所决定的某个规则选择将进入下一代的个体;
*/
private void select() {
double evals[] = new double[10]; // 所有染色体适应值
double p[] = new double[10]; // 各染色体选择概率
double q[] = new double[10]; // 累计概率
double F = 0; // 累计适应值总和
for (int i = 0; i < 10; i++) {
evals[i] = calculatefitnessvalue(ipop[i]);
if (best == null) {
best = new Best();
best.fitness = evals[i];
best.generations = 0;
best.str = ipop[i];
} else {
if (evals[i] > best.fitness) // 最好的记录下来
{
best.fitness = evals[i];
best.generations = gernation;
best.str = ipop[i];
}
}
F = F + evals[i]; // 所有染色体适应值总和

}
for (int i = 0; i < 10; i++) {
p[i] = evals[i] / F;
if (i == 0)
q[i] = p[i];
else {
q[i] = q[i - 1] + p[i];
}
}
for (int i = 0; i < 10; i++) {

double r = Math.random();
if (r <= q[0]) {
ipop[i] = ipop[0];

} else {
for (int j = 1; j < 10; j++) {
if (r < q[j]) {
ipop[i] = ipop[j];
break;
}
}
}
}
}

/**
* 交叉操作
* 交叉率为25%,平均为25%的染色体进行交叉
*/
private void cross() {
String temp1, temp2;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.25) {
double r = Math.random();
int pos = (int) (Math.round(r * 1000)) % GENE;
if (pos == 0) {
pos = 1;
}
temp1 = ipop[i].substring(0, pos)
+ ipop[(i + 1) % 10].substring(pos);
temp2 = ipop[(i + 1) % 10].substring(0, pos)
+ ipop[i].substring(pos);
ipop[i] = temp1;
ipop[(i + 1) / 10] = temp2;
}
}
}

/**
* 基因突变操作
* 1%基因变异m*pop_size 共180个基因,为了使每个基因都有相同机会发生变异,
* 需要产生[1--180]上均匀分布的
*/
private void mutation() {
for (int i = 0; i < 4; i++) {
int num = (int) (Math.random() * GENE * 10 + 1);
int chromosomeNum = (int) (num / GENE) + 1; // 染色体号

int mutationNum = num - (chromosomeNum - 1) * GENE; // 基因号
if (mutationNum == 0)
mutationNum = 1;
chromosomeNum = chromosomeNum - 1;
if (chromosomeNum >= 10)
chromosomeNum = 9;
//System.out.println("变异前" + ipop[chromosomeNum]);
String temp;
if (ipop[chromosomeNum].charAt(mutationNum - 1) == '0') {
if (mutationNum == 1) {
temp = "1" + ipop[chromosomeNum].substring

(mutationNum);
} else {
if (mutationNum != GENE) {
temp = ipop[chromosomeNum].substring(0, mutationNum -

1) + "1" + ipop

[chromosomeNum].substring(mutationNum);
} else {
temp = ipop[chromosomeNum].substring(0, mutationNum -
1) + "1";
}
}
} else {
if (mutationNum == 1) {
temp = "0" + ipop[chromosomeNum].substring

(mutationNum);
} else {
if (mutationNum != GENE) {
temp = ipop[chromosomeNum].substring(0, mutationNum -

1) + "0" + ipop

[chromosomeNum].substring(mutationNum);
} else {
temp = ipop[chromosomeNum].substring(0, mutationNum -
1) + "1";
}
}
}
ipop[chromosomeNum] = temp;
//System.out.println("变异后" + ipop[chromosomeNum]);
}
}
/**
* 执行遗传算法
*/
public String process() {
String str = "";
for (int i = 0; i < 10000; i++) {
this.select();
this.cross();
this.mutation();
gernation = i;
}
str = "最小值" + best.fitness + ",第" + best.generations + "个染色体";
return str;
}

}

热点内容
云服务器搭建网站哪家好 发布:2024-11-15 04:57:34 浏览:511
什么游戏最好玩又不吃配置 发布:2024-11-15 04:56:50 浏览:455
挤黑痘解压 发布:2024-11-15 04:51:13 浏览:732
nodejs编译js 发布:2024-11-15 04:51:13 浏览:599
买基金怎么配置合理 发布:2024-11-15 04:47:54 浏览:670
用友t3数据库类型 发布:2024-11-15 04:46:51 浏览:54
自己在家搭建服务器 发布:2024-11-15 04:25:04 浏览:648
箱娘免解压 发布:2024-11-15 04:24:58 浏览:38
热血宝宝脚本 发布:2024-11-15 04:23:31 浏览:225
正确的账号格式密码是什么样子的 发布:2024-11-15 04:18:41 浏览:24