遺傳演算(GA)程式設計

陳慶瀚

E-mail : pierre@isu.edu.tw

 

 

1. 原理

1.1 天擇(Selection)

1.2 交配(Crossover)

1.3 突變(Mutation)

2. 演算法

3. C++實作

 

 

 

 

原理

遺傳演算是一種隨機最佳化(stochastic optimization)的技術,其計算原理仿傚達爾文進化論的「物競天擇、適者生存」的概念來搜尋問題的最佳解。當待解的問題被視為一個函數,最佳解即可視為函數的最大值,而遺傳演算的目的即在於求出此一函數的最大值。

 

近年來,遺傳演算成為一股極受重視的技術潮流,我們歸納幾個重要的理由:

相對於其他最佳化技術─如最陡坡降法、模擬退火等方法,它可以應用在更多、更普遍的問題領域。當待解問題蘊含著非凸集(non-convex)、非連續(non-continuous)以及不可微分(non-differentiable)的特性時,甚至於待解問題本身無法以闡明(explicit)形式表達而僅能以程式來描述時,遺傳演算仍然具有解題的能力。

它具有本質上平行處理的機能(functionality)。在集體搜尋(population-based search)的策略下,遺傳演算平行地、多方向的搜尋問題領域的全域最佳解(global optimum),得以避開局部性最佳解。這種平行的機制有利於實現快速的大量平行處理器或者是VLSI的硬體架構。

它具有生物學或人類學的類比性。也就是說,遺傳演算是一種仿自然的計算(simulated natural computation),如同類神經網路一般,它模仿生物或自然界解決問題的方式。在普遍的生物系統中,到處可以觀察到自我組織、自我修復、自我改善的現象,對於這些智慧型機制的運作原理,我們的理解相當有限。但是自然界已經展示的這種機制的高度效能。遺傳演算應用演化理論來求解實境問題(real world problem)乃是朝向結合人造智慧與自然智慧的新趨勢之一。

 

1. 基本概念

 

考慮如下問題:若有一個6 位元的二元字串(binary string),每個位元可以填入01。現在定義函數

f(s) = 1在二元字串s的個數

當字串s = 000000, 我們得到f(000000) = 0, 而對於 s = 010010, f(010010) = 2。我們將使用遺傳演算來求解f(s)的最大值(亦即fmax(s*) = f(111111) = 6),藉由此一簡單的最佳化問題來觀察遺傳演算的運算過程。

首先將問題形式化,也就是將待解問題進行遺傳編碼。設有n個個體的族群Pn是一個固定的整數。族群的所有個體必須先以隨機的方式初值化,接著以f(s)分別評估其品質。在本例中,假設個體數目n = 5,以隨機的方式產生5個長度為6位元的二元字串後,分別得到評估函數值如下:

 

P(1)

s

f(s)

011011

100101

001010

001101

110100

4

3

2

3

3

P(1)表示第一代族群,我們將用它來產生品質更為優良的第二代族群P(2)。在遺傳演算中,任一代族群P(t+1)總是從前一代族群P(t)演化而來,此一原則得以使得新一代的可能的解總是立足在前一代業已存在的解,同時我們應用三種遺傳機制來探索新的、可能更佳的解:天擇(selection)、交配(crossover)和突變(mutation),因此決定兩代之間的遺傳可以表示成

P(t) >天擇─>Ps(t)>交配─>Pc(t)>突變─>P(t+1)

1.1 天擇(Selection)

 

Ps(t)是從P(t)的個體中隨機地選出n個作為新的個體,每個個體被選中的機率並不相同,而是與其評估函數值成正比:

 

計算第一代所有個體被選中的機率:

 

P(1)

s

f(s)

pselect

011011

100101

001010

001101

110100

4

3

2

3

3

4/(4+3+2+3+3)=0.27

0.20

0.13

0.20

0.20

 

輪盤(roulette wheel)方法被普遍應用在隨機選取個體。如圖一,每一個個體在輪盤上佔有一個正比於pselect的區間,一旦轉動輪盤,則目標落在任一個體的機率將與其所佔有的區間大小成正比。

-

依此概念,轉動輪盤5次,可以得到5個經由天擇的個體。這5個個體形成Ps(1)族群:

P(1)

 

Ps(1)

s

f(s)

 

s

f(s)

011011

100101

001010

001101

110100

4

3

2

3

3

>

天擇

011011

100101

011011

001101

110100

4

3

4

3

3

 

注意到這個天擇程序已經為我們複製較佳的個體s = 011011而淘汰了較差的個體s = 001010

 

1.2 交配(Crossover)

 

交配在於從Ps(1)族群中任意兩個個體交換其內容或重新組合,以形成新的個體。每一個個體都有pcross的機率被選出來配對。每一對(兩個)個體以隨機的方式決定一個位置將個體切開成兩部分,並將其中一部分與另一個體對換,如此形成兩個新的個體,例如:

0110|11

0110|01

1001|01

1001|11

 

 

 

01|1011

01|0100

11|0100

11|1011

    | 表示分割位置。新的個體產生後將取代它的父代個體,所形成的Pc(1)族群為:

 

Ps(1)

 

Pc(1)

s

f(s)

 

s

f(s)

011011

100101

011011

001101

110100

4

3

4

3

3

>

交配

011001

100111

010100

001101

111011

?

?

?

3

?

""表示尚未進行評估的個體。

 

1.3 突變(Mutation)

 

根據一個固定的突變機率 pmut,我們對族群Pc(1)的所有位元進行隨機式選取,被選取的位元將逆轉其值(0110)pmut的值一般在0.0010.01之間。假使 pmut = 0.05,此意味平均每100個位元就可能有5個位元接受突變。下表顯示一個突變後的結果:

 

Pc(1)

 

P(2)

s

f(s)

 

s

f(s)

011001

100111

010100

001101

111011

?

?

?

3

?

>

交配

111001

100101

010101

001101

111011

?

?

?

3

?

 

加上雙底線的10表示接受突變的位元。經過突變的運算後,我們最後得到了第二代族群P(2)。評估此一族群的品質:

 

P(2)

s

f(s)

111001

100101

010101

001101

111011

4

3

3

3

5

 

無論是最佳個體的評估函數值或是族群的評估函數值都顯然較第一代族群為佳。


 

 
 

2. 標準演算法和C++實作

 

2.1 標準的遺傳演算(或稱簡單遺傳演算─SGA)

 

步驟1:問題的編碼(Encoding)

將問題表示成二元字串的形式。上述範例欲求6位元的字串包含1的最大數目,這個簡單問題使我們可以使用6位元的二元字串作為族群的每一個個體的直接編碼。但對於一個參數最佳化的問題,每一個實數參數的二元編碼長度則視所須精確度來決定。對於變數x值域在 [a, b],如果需要小數點5位的精確度,意味x必須有(b - a)´105個可解析範圍,因此所須要的位元數目m可以由下式求出:

 

2m-1 < (b - a)´105 £ 2m-1

 

至於將二元字串解碼成實數公式如下:

 

x = a + decimal(binary_string)´

 

步驟2:族群的初始化(Initialization)

a. 設定族群要進行演化的迭代次數。

b. 決定族群的個體的數目N,一般介於十到數百之間,數目愈大則找到全域最佳值的機會愈大,但相對的其收斂速度愈慢。

c. 設定交配機率pcross和突變機率pmut

d. 隨機產生N個二元字串的個體vi, i = 1, 2, ..., N

 

步驟3:個體的評估(Evaluation)

a. 使用解碼公式把每一個體由二元字串binary_string轉成實數xii = 1, 2, ..., N

b. xi將代入評估函數求f(xi)

c. 轉換評估函數值為個體的品質指標(fitness)。對於最大化的問題,品質指標可簡單的令其等於評估函數值,亦即fitness(vi) = f(xi)

 

步驟4:天擇(Selection)

使用輪盤(roulette wheel)方法:

a. 先求出整體品質指標:

再針對每一個個體vi,計算其被選擇的機率:

最後依據個體的排序,計算累加機率qi

接著對於每個個體,執行步驟b, c

b. 產生一個範圍在 [0, 1] 的實數亂數r

c. 如果r £ q1,則選擇第一個個體;否則選擇第k個個體使得

qk-1< r £qk

 

步驟5:交配(crossover)

根據交配機率pcross,預期將有pcross´100 %的個體進行交配。

a. 對於每個個體vi,產生一個範圍在 [0, 1] 的實數亂數ri,如果ri £ pcross,選擇vi作為一個父代個體。所有被選出的父代個體兩兩排序預備交配。

b. 對每一對交配的父代個體vivk,使用單點交配(one-point-cut)方法,隨機的選擇一個位置pos,使兩個個體互相交換pos以右的所有位元,因為形成兩個新的個體v'iv'k

 

步驟6:突變(Mutation)

在整個族群中,我們預期有pmut´100 %的位元要接受突變,也就是pmut´m´N個位元,m是個體的位元數,N是族群的個體數。每一個位元都有同樣的機率接受突變,所以執行以下程序:

a. 隨機產生m´N個範圍在 [0, 1] 的實數亂數rj(j = 1, 2, ..., m´N) 如果rj < pmut,記錄其位元位置pos = j,表示該位置的位元值要接受突變。

b. 從所有突變的位置pos求出所屬的個體vi和處於該個體的位置bit_no

i     = quotient(pos / m);

bit_no = remainder (pos / m);

再反轉其位元值。

 

步驟7:判斷結束條件。

若已達到迭代次數G,就結束演算,否則回到步驟3,繼續下一代的演算。

 

 

 


最精簡的GA程式碼範例


 

1

#include <stdlib.h>

2

#include <time.h>

3

#include <math.h>

4

#include <fstream.h>

5

#include "randgen.h"

6

#include "array.h"

7

 

8

//

9

// BitArray object class for Genetic Algorithm

10

//

11

 

12

class BitArray: public Array1D<bool>

13

{

14

public:

15

  void Initialize(int n)

16

  {

17

    Array1D<bool>::Initialize(n);

18

    for(int i=0;i<nb;i++)m[i]=0;

19

  }

20

  void Randomize(unsigned long seed);

21

  void SetBit(int ndx, bool bit){m[ndx]=bit;}

22

  void SetBits(ifstream &in){for(int i=0;i<nb;i++)in>>m[i];}

23

  bool GetBit(int ndx){return m[ndx];}

24

  long ToDecimal();

25

  int HammingDistance(BitArray &by);

26

  void Print(ofstream& out){for(int i=0;i<nb;i++)out<<m[i];out<<endl;}

27

  void Print(){for(int i=0;i<nb;i++)cout<<m[i];cout<<endl;}

28

  bool operator==(BitArray &by);

29

};

30

 

31

void BitArray::Randomize(unsigned long seed)

32

{

33

  RanBit32 rbg(seed);

34

  for(int i = 0; i<nb; i++) m[i] = rbg.Next();

35

}

36

 

37

long BitArray::ToDecimal()

38

{

39

  long value = 0;

40

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

41

  {

42

    if(m[i])value += m[i]<<i;

43

  }

44

  return value;

45

}

46

 

47

int BitArray::HammingDistance(BitArray &by)

48

{

49

  int dist=0;

50

  for(int i=0;i<nb;i++)if(by.m[i]!=m[i])dist++;

51

  return dist;

52

}

53

 

54

bool BitArray::operator==(BitArray &by)

55

{

56

  if(by.nb!=nb)return false;

57

  bool flag=true;

58

  for(int i=0;i<nb;i++)if(by.m[i]!=m[i])

59

  {

60

    flag = false;

61

    break;

62

  }

63

  return flag;

64

}

65

 

66

 

67

//

68

// object class for Genetic Algorithm : Evaluator

69

//

70

 

71

class Evaluator

72

{

73

protected:

74

  int nb_variables;

75

  i1D nb_bits;

76

  Array1D<BitArray> BinaryVariable;

77

public:

78

  int GetTotalBits()

79

  {

80

    int total_bits=0;

81

    for(int i=0;i<nb_variables;i++)total_bits += nb_bits[i];

82

    return total_bits;

83

  }

84

  int GetNbVariable(){return nb_variables;}

85

  void Decompose(BitArray &bitarray);

86

  virtual double Evaluate(BitArray &bitarray,

87

                               double (*userfunc)(f1D &para))=0;

88

  virtual f1D& Decoding(BitArray &individ)=0;

89

};

90

 

91

void Evaluator::Decompose(BitArray &bitarray)

92

{

93

  int count=0;

94

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

95

  {

96

    for(int j=0;j<nb_bits.m[nb_variables-1-i];j++)

97

    {

98

      BinaryVariable[nb_variables-1-i].m[j]=bitarray.m[count];

99

      count++;

100

     }

101

  }

102

}

103

 

104

class NumericEvaluator : public Evaluator

105

{

106

protected:

107

  int total_bits;

108

  f1D min;

109

  f1D max;

110

public:

111

  f1D RealVariable;

112

  void Initialize(ifstream &in);

113

  f1D& Decoding(BitArray &individ);

114

  double Evaluate(BitArray &bitarray,

115

                  double (*userfunc)(f1D &para));

116

};

117

 

118

void NumericEvaluator::Initialize(ifstream &in)

119

{

120

  int required_precision;

121

  in>>nb_variables>>required_precision;

122

  int i,j, morder = required_precision-1;

123

  max.Initialize(nb_variables);

124

  min.Initialize(nb_variables);

125

  nb_bits.Initialize(nb_variables);

126

  BinaryVariable.Initialize(nb_variables);

127

  RealVariable.Initialize(nb_variables);

128

// define by case

129

  for(i=0;i<nb_variables;i++)

130

  {in>>min[i]>>max[i];}

131

  double *t=new double[nb_variables];

132

  for(i=0;i<nb_variables;i++)

133

    t[i] = double(max[i] - min[i])*pow10(morder);

134

  for(i=0;i<nb_variables;i++)nb_bits[i]=0;

135

  for(i=0;i<nb_variables;i++)

136

  {

137

    for(j=1;j<32;j++)if((t[i]>pow(2,j-1))&&(t[i]<=pow(2,j)))

138

    {nb_bits[i]=j; break;}

139

  }

140

  delete t;

141

  total_bits=0;

142

  for(i=0;i<nb_variables;i++)total_bits+=nb_bits[i];

143

  for(i=0;i<nb_variables;i++)

144

    BinaryVariable[i].Initialize(nb_bits[i]);

145

}

146

 

147

double NumericEvaluator::Evaluate(BitArray &bitarray,

148

        double (*userfunc)(f1D &para))

149

{

150

  if(bitarray.nb!=total_bits)return double(0.0);

151

  Decoding(bitarray);

152

  return userfunc(RealVariable);

153

}

154

 

155

f1D& NumericEvaluator::Decoding(BitArray &individ)

156

{

157

  Decompose(individ);

158

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

159

  {

160

    RealVariable[i]=BinaryVariable[i].ToDecimal();

161

    RealVariable[i]=min.m[i]+RealVariable[i]*(max.m[i]-min.m[i])

162

                   /(pow(2,nb_bits.m[i])-1.0);

163

  }

164

  return RealVariable;

165

}

166

 

167

//

168

// object class for Genetic Algorithm : population

169

//

170

 

171

class Population

172

{

173

protected:

174

  int generation;

175

  int nb_individ;

176

  int nb_bit;

177

  int optimal_individ_ndx;

178

  float CrossoverP;

179

  float MutationP;

180

  float ReserveP;

181

  float total_fitness;

182

  Ran32 GlbRan;

183

  Array1D<BitArray> individ, individtmp;

184

  f1D Fitness, AccFitness;

185

  f1D ProbaTable;

186

  Array1D<bool> Survivor;

187

  i1D ndx;

188

  int NSurvivor;

189

  BitArray CrossoverMask;

190

  void IndividCrossOver(BitArray &b1, BitArray &b2, int pos);

191

  void ConvertFitnessByOrder();

192

  void FindNBestIndivids(f1D &fit, int N);

193

public:

194

  void Initialize(int nindivid, int nbit);

195

  void Recording(Evaluator &eva, ofstream &out);

196

 

197

// Genetic mecanism

198

  f1D& Evaluate(Evaluator &eva, double (*userfunc)(f1D &para));

199

  void Evolution();

200

  void CrossOverOnePointCut();                 // one-point-cut crossover

201

  void CrossOverByMask(unsigned long seed);    // mask crossover

202

  void Mutation();

203

  void Selection();

204

 

205

// User interface

206

  void SetCrossOverProbability(float p){CrossoverP=p;}

207

  void SetMutationProbability(float p){MutationP=p;}

208

  int Get_Nb_Individ(){return nb_individ;}

209

  int Get_Nb_Bit(){return nb_bit;}

210

  BitArray& GetIndivid(int index);

211

  BitArray& GetOptimalIndivid();

212

  double GetOptimalFitness();

213

  double GetFitness(int index){return Fitness[index];}

214

  double GetTotalFitness(){return total_fitness;}

215

  void Print(ofstream& out);

216

  int GetOptimalIndividIndex(){return optimal_individ_ndx;}

217

};

218

 

219

void Population::Initialize(int nindivid, int nbit)

220

{

221

  nb_individ=nindivid;

222

  nb_bit=nbit;

223

// default values for CrossoverP, MutationP

224

  CrossoverP = 0.6;

225

  MutationP = 0.005;

226

  ReserveP = 0.1;

227

  unsigned long seed = (unsigned long)time(0);

228

  GlbRan.Reset(seed);

229

  for(int i=0;i<GlbRan.Next(0,10000);i++)seed=GlbRan.Next();

230

  GlbRan.Reset(seed);

231

  individ.Initialize(nb_individ);

232

  individtmp.Initialize(nb_individ*ReserveP);

233

  Fitness.Initialize(nb_individ);

234

  AccFitness.Initialize(nb_individ);

235

  ProbaTable.Initialize(nb_individ);

236

  Survivor.Initialize(nb_individ);

237

  ndx.Initialize(nb_individ);

238

  for(int i=0;i<individ.nb;i++)

239

  {

240

    individ.m[i].Initialize(nb_bit);

241

    individtmp.m[i].Initialize(nb_bit);

242

    individ.m[i].Randomize(GlbRan.Next());

243

  }

244

  CrossoverMask.Initialize(nb_bit);

245

  CrossoverMask.Randomize(GlbRan.Next());

246

  generation=0;

247

}

248

 

249

void Population::Recording(Evaluator &evaluator, ofstream &out)

250

{

251

  int i,j;

252

  f1D t;

253

  out<<endl<<"generation : "<<generation<<endl;

254

  for(i=0;i<nb_individ;i++)

255

  {

256

    t = evaluator.Decoding(individ[i]);

257

    out<<i<<"\tf(";

258

    for(j=0;j<evaluator.GetNbVariable();j++)out<<t[j]<<", ";out<<") = ";

259

    out<<Fitness[i]<<endl;

260

  }

261

  out<<"average fitness : "<<total_fitness/float(nb_individ)<<endl;

262

  out<<"optimal individual is : "<<optimal_individ_ndx<<endl;

263

  t = evaluator.Decoding(individ.m[optimal_individ_ndx]);

264

  out<<"optimal solution : "<<"\tf(";

265

  for(j=0;j<evaluator.GetNbVariable();j++)out<<t[j]<<", ";out<<") = ";

266

  out<<Fitness[optimal_individ_ndx];out<<endl;

267

}

268

 

269

void Population::IndividCrossOver(BitArray &b1, BitArray &b2, int pos)

270

{

271

  bool b;

272

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

273

  {

274

    b=b1.m[i];

275

    b1.m[i]=b2.m[i];

276

    b2.m[i]=b;

277

  }

278

}

279

 

280

void Population::ConvertFitnessByOrder()

281

{

282

  int i,j;

283

  for(i=0;i<nb_individ;i++)

284

  {

285

    AccFitness.m[i]=0;

286

    for(j=0;j<nb_individ;j++)if(Fitness.m[i]>Fitness.m[j])AccFitness.m[i]++;

287

  }

288

  for(i=0;i<nb_individ;i++)Fitness.m[i]=AccFitness.m[i];

289

}

290

 

291

void Population::Selection()

292

{

293

  int i,j;

294

  float sum=0.0;

295

  ConvertFitnessByOrder();

296

  for(i=0;i<nb_individ;i++)sum+=Fitness.m[i];

297

  for(i=0;i<nb_individ;i++)AccFitness.m[i]=Fitness.m[i]/sum;

298

  for(i=1;i<nb_individ;i++)AccFitness.m[i]+=AccFitness.m[i-1];

299

  fRan32 rg(GlbRan.Next());

300

  for(i=0;i<nb_individ;i++)ProbaTable.m[i]=rg.Next(0.0, 1.0);

301

  NSurvivor=0;

302

  for(i=0;i<nb_individ;i++)if(ProbaTable.m[i]<CrossoverP)

303

  {

304

    Survivor.m[i] = true;

305

    ndx.m[NSurvivor] = i;

306

    NSurvivor++;

307

  }

308

  NSurvivor = (NSurvivor/2)*2;

309

}

310

 

311

void Population::CrossOverOnePointCut()

312

{

313

  int i,n,a,b;

314

  Ran32 rg(GlbRan.Next());

315

  for(i=0;i<NSurvivor/2;i++)

316

  {

317

    a = rg.Next(0,NSurvivor);

318

    b = rg.Next(0,NSurvivor);

319

    n=rg.Next(0,nb_bit);

320

    IndividCrossOver(individ[ndx[a]],individ[ndx[b]],n);

321

  }

322

}

323

 

324

void Population::CrossOverByMask(unsigned long seed)

325

{

326

  int i,j,a,b;

327

  RanBit32 rbg(seed);

328

  for(i = 0; i< CrossoverMask.nb; i++) CrossoverMask.m[i] = rbg.Next();

329

  Ran32 rg(GlbRan.Next());

330

  bool t;

331

  for(i=0;i<NSurvivor/2;i++)

332

  {

333

    a = rg.Next(0,NSurvivor);

334

    b = rg.Next(0,NSurvivor);

335

    for(j=0;j<CrossoverMask.nb;j++)if(CrossoverMask.m[j]==1)

336

    {

337

      t = individ[ndx[a]].m[j];

338

      individ[ndx[a]].m[j] = individ[ndx[b]].m[j];

339

      individ[ndx[b]].m[j] = t;

340

    }

341

  }

342

}

343

 

344

void Population::Mutation()

345

{

346

  long length = nb_individ*nb_bit;

347

  int x, xd, xm;

348

  int nb_mt = int(MutationP*float(length)+0.5);

349

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

350

  {

351

    x = GlbRan.Next(0, length-1);

352

    xd = x/nb_bit;

353

    xm = x%nb_bit;

354

    if(individ[xd].m[xm]==0)individ[xd].m[xm]=1;

355

    else individ[xd].m[xm]=0;

356

   }

357

}

358

 

359

f1D& Population::Evaluate(Evaluator &evaluator, double (*userfunc)(f1D &para))

360

{

361

  int i;

362

  for(i=0;i<nb_individ;i++)

363

    Fitness.m[i]=evaluator.Evaluate(individ.m[i], userfunc);

364

  float max=-1e30;

365

  for(i=0;i<nb_individ;i++)if(Fitness.m[i]>max)

366

  {

367

    max=Fitness.m[i];

368

    optimal_individ_ndx=i;

369

  }

370

  total_fitness=0;

371

  for(i=0;i<nb_individ;i++)total_fitness += Fitness.m[i];

372

  return Fitness;

373

}

374

 

375

void Population::FindNBestIndivids(f1D &fit, int N)

376

{

377

 

378

}

379

 

380

void Population::Evolution()

381

{

382

  Selection();

383

//  CrossOverByMask(GlbRan.Next());

384

  CrossOverOnePointCut();

385

  Mutation();

386

  generation++;

387

}

388

 

389

BitArray& Population::GetIndivid(int ndx)

390

{

391

  return individ[ndx];

392

}

393

 

394

BitArray& Population::GetOptimalIndivid()

395

{

396

  return individ[optimal_individ_ndx];

397

}

398

 

399

double Population::GetOptimalFitness()

400

{

401

  return Fitness[optimal_individ_ndx];

402

}

403

 

404

void Population::Print(ofstream& out)

405

{

406

  for(int i=0;i<nb_individ;i++)individ[i].Print(out);

407

}

408

 

409

 

410

double user_evaluation_function(f1D &v)

411

{

412

  return -(v[0]*v[0] + v[1]*v[1]);

413

}

 

 

 

 

 

 

414

// Testing main program

415

main()

416

{

417

  char key;

418

  char filename[128];

419

  cout<<"Input filename of parameter description data : ";

420

  cin>>filename;

421

  ifstream in(filename);

422

  ofstream out("ga.dat");

423

  if(!in){cout<<"Cannot open file! Any key to terminate...";cin>>key;exit(1);}

424

  NumericEvaluator evaluator;

425

  evaluator.Initialize(in);

426

  Population population;

427

  SetCrossOverProbability(0.6);

428

  SetMutationProbability(0.02);

429

  int generation, nb_individ;

430

  cout<<"\nEnter number of individuals in the population : ";cin>>nb_individ;

431

  cout<<"\nEnter number of iteration for evolution : ";cin>>generation;

432

  population.Initialize(nb_individ, evaluator.GetTotalBits());

433

  population.Evaluate(evaluator, user_evaluation_function);

434

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

435

  {

436

    population.Evolution();

437

    population.Evaluate(evaluator,user_evaluation_function);

438

    population.Recording(evaluator, out);

439

    cout<<i<<endl;

440

  }

441

  cout<<endl<<"The evolution process is saved in ga.dat"<<endl;

442

  cout<<"any key to terminate...";

443

  cin>>key;

444

}

 

 

謝孟媛 dvd -
情趣用品 -
飛鳥遊戲 -
遊戲基地 -
PATEK PHILIPPE -
xyz資訊工作坊 -
xyz軟體王 -
英文老師 -
沛納海 -
xyz軟體下載倉庫 -
基測試題 -
CARTIER 卡地亞 -
林晟數學 -
PIAGET -
費洛蒙情定 -
xyz -
軟體大補帖 -
高國華補習班 -
game淘 -
ps2台片 -
wii超級瑪莉攻略 -
情定費洛蒙 -
wii價格2011 -
xbox 360台片 -
tvgame360 -
愛馬仕 -
春藥專賣店 -
ps3價錢 2011 -
ps2遊戲王 -
wii遊戲片專賣店 -
百達翡麗 PATEK PHILIPPE -
壯陽藥品哪買 -
海賊王 -
春藥王 -
xyz軟體下載倉庫 -
壯陽食物 -
xbox360 -
催情藥 -
TISSOT 天梭 -
ps2遊戲燒錄 -
威而剛哪裡買 -
一夜情婦 -
xbox 360台片專賣 -
國中基測題庫 -
無雙遊戲網 -
xyz軟體王 -
ps2遊戲片80元 -
基測 -
xyz軟體王下載 -
GUCCI 古馳 -
南一題庫網 -
COACH -
LOUIS VUITTON -
wii超級瑪莉 -
wii價格2011 -
魔法老師 -
催情藥專賣店 -
國小翰林題庫網 -
wii遊戲片專賣店 -
遊戲天堂 -
寶格麗 -
金榜之路 -
wii遊戲片80元 -
xbox 360遊戲片 -
wii遊戲載點 -
人類費洛蒙情定 -
xbox 360台片專賣 -
催情王 -
xyz軟體之家 -
ps2遊戲片80元 -
情色小站 -
微風廣場 -
情慾之夜 -
民視文化 -
xbox360 -
蔻馳 -
ps2遊戲燒錄 -
ps3遊戲片 -
龍騰高中題庫 -
ps3台片 -
威而剛 -
ps3價錢 2011 -
軟體王下載 -
蕭邦 CHOPARD -
龍騰 -
催情藥 -
威而剛哪裡買 -
基測題目 -
HERMES 愛馬仕 -
情定費洛蒙 -
ps2台片 -
ps3遊戲片 -
wii瑪莉兄弟遊戲 -
江詩丹頓 Vacheron Constantin -
wii超級瑪莉 -
wii遊戲片在ho99小舖 -
春藥王 -
歷屆基測試題 -
窮人軟體 -
威而柔哪裡買 -
蕭邦 -
翰林題庫網 -
一夜情婦 -
wii遊戲下載 -
xbox 360遊戲 -
壯陽食物 -
ps2遊戲片 -
sogo百貨 -
台灣情色網 -
xyz軟體王下載 -
lv2011官方網 -
wii遊戲片專賣店 -
xbox 360價錢 -
歐米茄 -
雷達錶 RADO -
xyz資訊工坊 -
儒林補習班 -
壯陽藥品 -
xyz軟體王 -
窮人遊戲 -
ps2遊戲下載 -
ps3台片 -
德周 -
sogo百貨 -
費洛蒙情定 -
壯陽藥品哪買 -
催情王 -
春藥哪裡買 -
lv2011夏季新款 -
情趣用品 -
中友百貨 -
史萊姆的第一個家 -
情色論壇 -
萬寶龍 MONT BLANC -
萬國 -
ps2遊戲下載 -
春藥哪裡買 -
xyz資訊工作坊 -
龍騰文化 -
太平洋百貨 -
軟體王 -
xbox 360台片專賣 -
ps3遊戲片在ho99小舖 -
壯陽藥 -
xyz軟體銀行 -
xbox360台片 -
魔法24 -
wii遊戲片80元 -
XYZ資訊工坊 -
CARTIER -
春藥網 -
壯陽 -
xyz 軟體補給站 -
微風廣場 -
lv2011新款型錄 -
xbox 360遊戲 -
費洛蒙 -
卡地亞 -
wii遊戲下載 -
窮人天碟 -
春藥專賣店 -
gucci2011專賣店旗艦店 -
迪奧 -
CHANEL -
xyz軟體大本營 -
xbox 360遊戲片在ho99小舖 -
台北郵購網 -
BURBERRY 巴寶莉 -
伯爵 -
遠東百貨 -
陳希 -
費洛蒙mx -
時間廣場 -
漢神百貨 -
情色論壇 -
傳政 -
軟體 -
寶格麗 BVLGARI -
名牌包俱樂部 -
時間廣場 -
威而柔 -
wii瑪莉兄弟遊戲 -
lv名牌包專賣店 -
xyz軟體大本營 -
威而柔哪裡買 -
伯爵 PIAGET -
xyz軟體銀行 -
ps3遊戲下載 -
wii超級瑪莉歐 -
無名套裝 -
xyz軟體下載倉庫 -
江詩丹頓 -
林晟 -
ps3遊戲片在ho99小舖 -
威而剛 -
費洛蒙mx -
xyz軟體之家 -
HERMES -
林晟超理解數學 -
謝孟媛 -