?? 電梯動(dòng)力學(xué)參數(shù)寫(xiě)的簡(jiǎn)單遺傳算法(程序帶目標(biāo)函數(shù)值、適應(yīng)度值計(jì)算,但是我的適應(yīng)度函數(shù)因?yàn)槟繕?biāo)函數(shù)的計(jì)算很特殊,一起放在了程序外面計(jì)算,在此不提供)。.txt
字號(hào):
頭文件:
// CMVSOGA.h : main header file for the CMVSOGA.cpp
////////////////////////////////////////////////////////////////////
///// /////
///// 沈陽(yáng)航空工業(yè)學(xué)院 動(dòng)力工程系 /////
///// 作者:李立新 /////
///// 完成日期:2006.08.02 /////
///// /////
////////////////////////////////////////////////////////////////////
// 本來(lái)想使用鏈表里面套鏈表的,程序調(diào)試比較麻煩,改為種群用鏈表表示
//染色體固定為16的方法。
#if !defined(AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_)
#define AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Afxtempl.h"
#define variablenum 16
class CMVSOGA
{
public:
CMVSOGA();
void selectionoperator();
void crossoveroperator();
void mutationoperator();
void initialpopulation(int, int ,double ,double,double *,double *); //種群初始化
void generatenextpopulation(); //生成下一代種群
void evaluatepopulation(); //評(píng)價(jià)個(gè)體,求最佳個(gè)體
void calculateobjectvalue(); //計(jì)算目標(biāo)函數(shù)值
void calculatefitnessvalue(); //計(jì)算適應(yīng)度函數(shù)值
void findbestandworstindividual(); //尋找最佳個(gè)體和最差個(gè)體
void performevolution();
void GetResult(double *);
void GetPopData(double **);
void SetValueData(double *);
void maxandexpectation();
private:
struct individual
{
double chromosome[variablenum]; //染色體編碼長(zhǎng)度應(yīng)該為變量的個(gè)數(shù)
double value;
double fitness; //適應(yīng)度
};
double variabletop[variablenum]; //變量值
double variablebottom[variablenum]; //變量值
int popsize; //種群大小
// int generation; //世代數(shù)
int best_index;
int worst_index;
double crossoverrate; //交叉率
double mutationrate; //變異率
int maxgeneration; //最大世代數(shù)
struct individual bestindividual; //最佳個(gè)體
struct individual worstindividual; //最差個(gè)體
struct individual current; //當(dāng)前個(gè)體
struct individual current1; //當(dāng)前個(gè)體
struct individual currentbest; //當(dāng)前最佳個(gè)體
CList <struct individual,struct individual &> population; //種群
CList <struct individual,struct individual &> newpopulation; //新種群
CList <double,double> cfitness; //存儲(chǔ)適應(yīng)度值
// double maxfitness;
// double minfitness;
// double avefitness;
//怎樣使鏈表的數(shù)據(jù)是一個(gè)結(jié)構(gòu)體????主要是想把種群作成鏈表。節(jié)省空間。
};
#endif
執(zhí)行文件
// CMVSOGA.cpp : implementation file
//
#include "stdafx.h"
#include "CMVSOGA.h"
#include "math.h"
#include "stdlib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMVSOGA.cpp
void CMVSOGA::initialpopulation(int ps, int gen ,double cr ,double mr,double *xtop,double *xbottom) //第一步,初始化。
{
int i ,j;
popsize=ps ;
maxgeneration=gen;
crossoverrate=cr;
mutationrate =mr;
for (i=0;i<variablenum;i++)
{
variabletop[i] =xtop[i];
variablebottom[i] =xbottom[i];
}
srand( (unsigned)time( NULL ) );
for(i=0;i<popsize;i++)
{
for (j=0;j<variablenum ;j++)
{
current.chromosome[j]=double(rand()%1000)/1000*(variabletop[j]-variablebottom[j])+variablebottom[j];
}
current.fitness=0;
current.value=0;
population.InsertAfter(population.FindIndex(i),current);//除了初始化使用insertafter外,其他的用setat命令。
}
}
void CMVSOGA::generatenextpopulation()//第三步,生成下一代。
{
selectionoperator();
crossoveroperator();
mutationoperator();
}
void CMVSOGA::evaluatepopulation() //第二步,評(píng)價(jià)個(gè)體,求最佳個(gè)體
{
// calculateobjectvalue();
calculatefitnessvalue(); //在此步中因該按適應(yīng)度值進(jìn)行排序.鏈表的排序.
findbestandworstindividual();
}
void CMVSOGA:: calculateobjectvalue() //計(jì)算函數(shù)值,應(yīng)該由外部函數(shù)實(shí)現(xiàn)。主要因?yàn)槟繕?biāo)函數(shù)很復(fù)雜。
{
int i,j;
double x[variablenum];
for (i=0; i<popsize; i++)
{
current=population.GetAt(population.FindIndex(i));
current.value=0;
//使用外部函數(shù)進(jìn)行,在此只做結(jié)果的傳遞。
for (j=0;j<variablenum;j++)
{
x[j]=current.chromosome[j];
current.value=current.value+(j+1)*pow(x[j],4);
}
////使用外部函數(shù)進(jìn)行,在此只做結(jié)果的傳遞。
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA::mutationoperator() //對(duì)于浮點(diǎn)數(shù)編碼,變異算子的選擇具有決定意義。
//需要guass正態(tài)分布函數(shù),生成方差為sigma,均值為浮點(diǎn)數(shù)編碼值c。
{
int i,j;
double r1,r2,p,sigma;//sigma高斯變異參數(shù)
sigma=0.5;
for (i=0;i<popsize;i++)
{
current=population.GetAt(population.FindIndex(i));
//生成均值為current.chromosome,方差為sigma的高斯分布數(shù)
srand((unsigned int) time (NULL));
for(j=0; j<variablenum; j++)
{
r1 =double( rand()%1001)/1000;
r2 = double(rand()%1001)/1000;
p=double(rand()%1000)/1000;
if(p<mutationrate)
{
//高斯變異
current.chromosome[j] = (current.chromosome[j]
+ sigma*sqrt(-2*log(r1)/0.4323)*sin(2*3.1415926*r2));
if (current.chromosome[j]>variabletop[j])
{
current.chromosome[j]=variabletop[j];
}
if (current.chromosome[j]<variablebottom [j])
{
current.chromosome[j]=variablebottom [j];
}
}
}
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA::selectionoperator() //從當(dāng)前個(gè)體中按概率選擇新種群,應(yīng)該加一個(gè)復(fù)制選擇,提高種群的平均適應(yīng)度
//第二次循環(huán)出錯(cuò)
{
int i,j,pindex=0;
double p,pc,sum=0;
i=0;
j=0;
pindex=0;
p=0;
pc=0;
sum=0.001;
newpopulation.RemoveAll();
cfitness.RemoveAll();
//鏈表排序
// population.SetAt (population.FindIndex(0),current); //多余代碼
for (i=1;i<popsize;i++)
{
current=population.GetAt(population.FindIndex(i));
for(j=0;j<i;j++) //從小到大用before排列。
{
current1=population.GetAt(population.FindIndex(j));//臨時(shí)借用變量
if(current.fitness<=current1.fitness)
{
population.InsertBefore(population.FindIndex(j),current);
population.RemoveAt(population.FindIndex(i+1));
break;
}
}
// m=population.GetCount();
}
//鏈表排序
for(i=0;i<popsize;i++)//求適應(yīng)度總值,以便歸一化,是已經(jīng)排序好的鏈。
{
current=population.GetAt(population.FindIndex(i));
sum+=current.fitness;
}
for(i=0;i<popsize; i++)//歸一化
{
current=population.GetAt(population.FindIndex(i));
current.fitness=current.fitness/sum;
cfitness.InsertAfter (cfitness .FindIndex(i),current.fitness);
}
for(i=1;i<popsize; i++)//概率值從小到大;
{
current.fitness=cfitness.GetAt (cfitness.FindIndex(i-1))
+cfitness.GetAt(cfitness.FindIndex(i)); //歸一化
cfitness.SetAt (cfitness .FindIndex(i),current.fitness);
population.SetAt(population.FindIndex(i),current);
}
for (i=0;i<popsize;)//輪盤賭概率選擇。本段還有問(wèn)題。
{
p=double(rand()%1000)/1000+0.0001; //隨機(jī)生成概率
pindex=0; //遍歷索引
pc=cfitness.GetAt(cfitness .FindIndex(0));
while(p>=pc&&pindex<popsize) //問(wèn)題所在。
{
pc=cfitness.GetAt(cfitness .FindIndex(pindex));
pindex++;
}
//必須是從index~popsize,選擇高概率的數(shù)。即大于概率p的數(shù)應(yīng)該被選擇,選擇不滿則進(jìn)行下次選擇。
for (j=popsize-1;j<pindex&&i<popsize;j--)
{
newpopulation.InsertAfter (newpopulation.FindIndex(0),
population.GetAt (population.FindIndex(j)));
i++;
}
}
for(i=0;i<popsize; i++)
{
population.SetAt (population.FindIndex(i),
newpopulation.GetAt (newpopulation.FindIndex(i)));
}
// j=newpopulation.GetCount();
// j=population.GetCount();
newpopulation.RemoveAll();
}
//current 變化后,以上沒(méi)有問(wèn)題了。
void CMVSOGA:: crossoveroperator() //非均勻算術(shù)線性交叉,浮點(diǎn)數(shù)適用,alpha ,beta是(0,1)之間的隨機(jī)數(shù)
//對(duì)種群中兩兩交叉的個(gè)體選擇也是隨機(jī)選擇的。也可取beta=1-alpha;
//current的變化會(huì)有一些改變。
{
int i,j;
double alpha,beta;
CList <int,int> index;
int point,temp;
double p;
srand( (unsigned)time( NULL ) );
for (i=0;i<popsize;i++)//生成序號(hào)
{
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -