分享
 
 
 

由SAT问题展开说(2)[演化计算c#实现下]

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

SAT问题展开说(2)[下]

首先,我们看使用何种适应度函数。事实上,对于染色体组,我们好坏的评价由score来记录,如下的过程自然刻画了我们对适应度函数的设计:

private int GetScore(int i)

{

int score=0;

for(int j=0;j<maxNum;j++)

for(int k=0;k<valNum;k++)

if(int.Parse(satGenes[i].ToString().Substring(k,1))+bSentence[j,k]==2//

||int.Parse(satGenes[i].ToString().Substring(k,1))+bSentence[j,k]==-1)

{

score++;

break;

}

return score;

}

public int Sort()

{

int iBest=0,iWorst=0;

int bestScore=GetScore(0);//

int worstScore=GetScore(0);

for(int i=0;i<maxNum;i++)

{

score[i]=GetScore(i);

if(score[i]>bestScore)

{

iBest=i;

bestScore=score[i];

}

else if(score[i]<worstScore)

{

iWorst=i;

worstScore=score[i];

}

}

best=new StringBuilder(satGenes[iBest].ToString());

worst=new StringBuilder(satGenes[iWorst].ToString());

return bestScore;

}

您注意到,演化策略我们采取的又不同于一般的遗传算法。当然,使用best和worst,使得演化的压力异常的大,但我们对于算子的设计是多样的,以避免早熟现象的出现。

现在是最为核心的部分,遗传算子的设计。

我们的算法中,杂交算子和变异算子都是非常多样化的。其中变异算子以Pm的概率值使一个染色体进行如下的变异:

1/3的情况进行某一位的取反变异,或以2/3的情况进行某连续两位的取反变异。

而杂交算子以Pc的概率值使两个染色体进行杂交,杂交过程如下:

从某位开始,以某个随机长度,2/3的情况进行互换子串进行杂交,1/3的情况进行异或杂交。

过程分别如下:

public void Mutation()

{

int mutType,start;

string subGene;

int i=randNum.Next(maxNum-1);

if(randNum.NextDouble()<=Pm)

{

mutType=randNum.Next(0,2);

switch(mutType)

{

case 0:

start=randNum.Next(0,valNum-1);

subGene=satGenes[i].ToString().Substring(start,1);

if(subGene=="0")

satGenes[i].Replace("0","1",start,1);

else

satGenes[i].Replace("1","0",start,1);

break;

case 1:case 2:

start=randNum.Next(0,valNum-2);

subGene=satGenes[i].ToString().Substring(start,2);

switch(subGene)

{

case "00":

satGenes[i].Replace("00","11",start,2);

break;

case "01":

satGenes[i].Replace("01","10",start,2);

break;

case "10":

satGenes[i].Replace("10","01",start,2);

break;

case "11":

satGenes[i].Replace("11","00",start,2);

break;

}

break;

default:

break;

}

}

}

public void Crossover()

{

int croType,start,length,i,j;

string i_subGene,j_subGene;

length=randNum.Next(5)+1;

start=randNum.Next(0,valNum-length);

i=randNum.Next(maxNum-1);

j=randNum.Next(maxNum-1);

i_subGene=satGenes[i].ToString().Substring(start,length);

j_subGene=satGenes[j].ToString().Substring(start,length);

croType=randNum.Next(2);

switch(croType)

{

case 0:case 2:

satGenes[i].Replace(i_subGene,j_subGene,start,length);

satGenes[j].Replace(j_subGene,i_subGene,start,length);

break;

case 1:

for(int k=0;k<length;k++)

{

switch(int.Parse(i_subGene.Substring(k,1))

+int.Parse(j_subGene.Substring(k,1)))

{

case 0:case 2:

satGenes[i].Replace(i_subGene.Substring(k,1),"1",start+k,1);

satGenes[j].Replace(j_subGene.Substring(k,1),"0",start+k,1);

break;

case 1:

satGenes[i].Replace(i_subGene.Substring(k,1),"0",start+k,1);

satGenes[j].Replace(j_subGene.Substring(k,1),"1",start+k,1);

break;

}

}

break;

default:

break;

}

}

以上是SAT类的主要部分。这样算法的细节设计过程已经实现了。

下面是算法过程,以及初始化过程和其他界面过程,在类Form1中实现,另外修改演化参数的类frmSet我们就不在此介绍了(因为它不关系算法实现)。

这里是算法本身:

private void geneCompute()

{

int answer=0,oldAnswer=0;

hh=DateTime.Now.Hour;

mm=DateTime.Now.Minute;

ss=DateTime.Now.Second;

ms=DateTime.Now.Millisecond;

SetTime();

oneSAT.InitGenes();

oldAnswer=answer=oneSAT.Sort();

while(answer<maxNum-nilNum)

{

oneSAT.Mutation();

oneSAT.Crossover();

answer=oneSAT.Sort();

spScore.Text=strScore+answer.ToString();

if(answer<oldAnswer)

{

oldAnswer=answer;

chListBoxString.Items.Add(oneSAT.Best,true);

}

SetTime();

}

chListBoxString.ClearSelected();

chListBoxString.Items.Add(oneSAT.Best,true);

spScore.Text=strScore+answer.ToString();

}

其中oneSAT是SAT类的一个对象,初始化如下:

oneSAT=new SAT(maxNum,valNum,0.8,0.02);

SetTime()是计算算法执行时间的跟踪,详细过程可见附录。而整个算法的执行,我们新创建一个线程computeGene,其过程如下:

private void threadGeneCompute()

{

computeGene=new Thread(new ThreadStart(geneCompute));

computeGene.Start();

}

这样,在类Form1中,我们可以控制这个线程computeGene来进行我们算法的数值实验了。

算法的参数设置如下:

l 逻辑变量规模:200 和 300

l 种群规模:30

l 子句数量:30

l 杂交概率:0.8

l 变异概率:0.02

l 算法的出口为最好的染色体的分数等于非空的子句数量

我们选择200和300个的逻辑变量分别做了若干次实验,除去一开始就寻到结果的瞬时解答外,我们各随机选择了两个子句集与其计算结果、时间。分别为:

逻辑变量数目为200的:

其一,计算结果为:

00000000000000010000000000000000000011100000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000000000000000000

0000011000000000000000000000000000000000

时间为: 13s 328ms

其二,计算结果为:

00000111100100000000011110000011000000000000000110101110000000000001100000011111

00000000000100000000000000000000000000000010000000000000001100000000100000110000

0000000001000000011110000010000001111100

时间为: 57s 563ms

逻辑变量数目为300的:

其一,计算结果为:

00000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000111100000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000000000000000

时间为: 2s 625ms

其二,计算结果为:

00001000000000000000000000000000000000000000111000000000000000000000000000000000

00000000000000000000000100000000000000000000000000001100000000000000000000000000

00000000000000000000010000000000000011110000000000000001111100000000000000000000

000000000000000000000000000000010000000000000000000000000000

时间为: 28s 641ms

子句集合都是随机生成的,我们附录在后面供读者参考。由答案的结果来看,复杂的子句需要较多的时间,但相应于2^200 和2^300的问题规模,计算速度还是可观的。

存在的问题

算法是我们上学期实现,后来由于忙于其他事情,再没有做细致的优化工作。所以现在看来,算法的可改进尝试点还是很多的。简单分析如下,而更多的提高,我们寄希望于读者。如果您对整个程序的源码有兴趣,可联系笔者,免费赠送。

首先,演化策略还比较单调。我们实际上采取的是,对一个种群,择其一按概率要求进行变异和杂交,然后排序去除最差者。没有其他的任何措施,比如好基因可以保留为一个库等。这里可以尝试改进。

算法在执行的过程中,有少量情况是,分数降低1分,但很快又还原。这表明计算不是一直向前的。而且,在计算结果趋于较好时,计算也放慢,应该想办法进行加速而有所补救。

最大的缺憾是,在最终结果出现之前,我们不能判定该集合是否是可满足的。我们只能告诉您,目前的计算结果表明,有多少子句已经可以满足,而我们希望情况越来越好。这是由演化计算的特点所决定的,改进难于实现。

算子还可以试图采取其他方案。但我们认为我们的算子设计还是较好的。

参考资料:

(1)康立山,智能计算及其应用讲义,中国地质大学内部讲义,2002年9月

(2)Harry R.Lewis/Christos H.Papadimitriou, ELEMENTS OF THE THEORY OF COMPUTATION ,清华大学出版社(影印),1999年9月

(2)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有