遺傳演算法編程
Ⅰ 遺傳演算法的C語言實現
一個非常簡單的遺傳演算法源代碼,是由Denis Cormier (North Carolina State University)開發的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。代碼保證盡可能少,實際上也不必查錯。對一特定的應用修正此代碼,用戶只需改變常數的定義並且定義「評價函數」即可。注意代碼的設計是求最大值,其中的目標函數只能取正值;且函數值和個體的適應值之間沒有區別。該系統使用比率選擇、精華模型、單點雜交和均勻變異。如果用Gaussian變異替換均勻變異,可能得到更好的效果。代碼沒有任何圖形,甚至也沒有屏幕輸出,主要是保證在平台之間的高可移植性。讀者可以從ftp.uncc.e,目錄 coe/evol中的文件prog.c中獲得。要求輸入的文件應該命名為『gadata.txt』;系統產生的輸出文件為『galog.txt』。輸入的文件由幾行組成:數目對應於變數數。且每一行提供次序——對應於變數的上下界。如第一行為第一個變數提供上下界,第二行為第二個變數提供上下界,等等。
/**************************************************************************/
/* This is a simple genetic algorithm implementation where the */
/* evaluation function takes positive values only and the */
/* fitness of an indivial is the same as the value of the */
/* objective function */
/**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Change any of these parameters to match your needs */
#define POPSIZE 50 /* population size */
#define MAXGENS 1000 /* max. number of generations */
#define NVARS 3 /* no. of problem variables */
#define PXOVER 0.8 /* probability of crossover */
#define PMUTATION 0.15 /* probability of mutation */
#define TRUE 1
#define FALSE 0
int generation; /* current generation no. */
int cur_best; /* best indivial */
FILE *galog; /* an output file */
struct genotype /* genotype (GT), a member of the population */
{
double gene[NVARS]; /* a string of variables */
double fitness; /* GT's fitness */
double upper[NVARS]; /* GT's variables upper bound */
double lower[NVARS]; /* GT's variables lower bound */
double rfitness; /* relative fitness */
double cfitness; /* cumulative fitness */
};
struct genotype population[POPSIZE+1]; /* population */
struct genotype newpopulation[POPSIZE+1]; /* new population; */
/* replaces the */
/* old generation */
/* Declaration of proceres used by this genetic algorithm */
void initialize(void);
double randval(double, double);
void evaluate(void);
void keep_the_best(void);
void elitist(void);
void select(void);
void crossover(void);
void Xover(int,int);
void swap(double *, double *);
void mutate(void);
void report(void);
/***************************************************************/
/* Initialization function: Initializes the values of genes */
/* within the variables bounds. It also initializes (to zero) */
/* all fitness values for each member of the population. It */
/* reads upper and lower bounds of each variable from the */
/* input file `gadata.txt'. It randomly generates values */
/* between these bounds for each gene of each genotype in the */
/* population. The format of the input file `gadata.txt' is */
/* var1_lower_bound var1_upper bound */
/* var2_lower_bound var2_upper bound ... */
/***************************************************************/
void initialize(void)
{
FILE *infile;
int i, j;
double lbound, ubound;
if ((infile = fopen("gadata.txt","r"))==NULL)
{
fprintf(galog,"\nCannot open input file!\n");
exit(1);
}
/* initialize variables within the bounds */
for (i = 0; i < NVARS; i++)
{
fscanf(infile, "%lf",&lbound);
fscanf(infile, "%lf",&ubound);
for (j = 0; j < POPSIZE; j++)
{
population[j].fitness = 0;
population[j].rfitness = 0;
population[j].cfitness = 0;
population[j].lower[i] = lbound;
population[j].upper[i]= ubound;
population[j].gene[i] = randval(population[j].lower[i],
population[j].upper[i]);
}
}
fclose(infile);
}
/***********************************************************/
/* Random value generator: Generates a value within bounds */
/***********************************************************/
double randval(double low, double high)
{
double val;
val = ((double)(rand()%1000)/1000.0)*(high - low) + low;
return(val);
}
/*************************************************************/
/* Evaluation function: This takes a user defined function. */
/* Each time this is changed, the code has to be recompiled. */
/* The current function is: x[1]^2-x[1]*x[2]+x[3] */
/*************************************************************/
void evaluate(void)
{
int mem;
int i;
double x[NVARS+1];
for (mem = 0; mem < POPSIZE; mem++)
{
for (i = 0; i < NVARS; i++)
x[i+1] = population[mem].gene[i];
population[mem].fitness = (x[1]*x[1]) - (x[1]*x[2]) + x[3];
}
}
/***************************************************************/
/* Keep_the_best function: This function keeps track of the */
/* best member of the population. Note that the last entry in */
/* the array Population holds a of the best indivial */
/***************************************************************/
void keep_the_best()
{
int mem;
int i;
cur_best = 0; /* stores the index of the best indivial */
for (mem = 0; mem < POPSIZE; mem++)
{
if (population[mem].fitness > population[POPSIZE].fitness)
{
cur_best = mem;
population[POPSIZE].fitness = population[mem].fitness;
}
}
/* once the best member in the population is found, the genes */
for (i = 0; i < NVARS; i++)
population[POPSIZE].gene[i] = population[cur_best].gene[i];
}
/****************************************************************/
/* Elitist function: The best member of the previous generation */
/* is stored as the last in the array. If the best member of */
/* the current generation is worse then the best member of the */
/* previous generation, the latter one would replace the worst */
/* member of the current population */
/****************************************************************/
void elitist()
{
int i;
double best, worst; /* best and worst fitness values */
int best_mem, worst_mem; /* indexes of the best and worst member */
best = population[0].fitness;
worst = population[0].fitness;
for (i = 0; i < POPSIZE - 1; ++i)
{
if(population[i].fitness > population[i+1].fitness)
{
if (population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if (population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i + 1;
}
}
else
{
if (population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if (population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i + 1;
}
}
}
/* if best indivial from the new population is better than */
/* the best indivial from the previous population, then */
/* the best from the new population; else replace the */
/* worst indivial from the current population with the */
/* best one from the previous generation */
if (best >= population[POPSIZE].fitness)
{
for (i = 0; i < NVARS; i++)
population[POPSIZE].gene[i] = population[best_mem].gene[i];
population[POPSIZE].fitness = population[best_mem].fitness;
}
else
{
for (i = 0; i < NVARS; i++)
population[worst_mem].gene[i] = population[POPSIZE].gene[i];
population[worst_mem].fitness = population[POPSIZE].fitness;
}
}
/**************************************************************/
/* Selection function: Standard proportional selection for */
/* maximization problems incorporating elitist model - makes */
/* sure that the best member survives */
/**************************************************************/
void select(void)
{
int mem, i, j, k;
double sum = 0;
double p;
/* find total fitness of the population */
for (mem = 0; mem < POPSIZE; mem++)
{
sum += population[mem].fitness;
}
/* calculate relative fitness */
for (mem = 0; mem < POPSIZE; mem++)
{
population[mem].rfitness = population[mem].fitness/sum;
}
population[0].cfitness = population[0].rfitness;
/* calculate cumulative fitness */
for (mem = 1; mem < POPSIZE; mem++)
{
population[mem].cfitness = population[mem-1].cfitness +
population[mem].rfitness;
}
/* finally select survivors using cumulative fitness. */
for (i = 0; i < POPSIZE; i++)
{
p = rand()%1000/1000.0;
if (p < population[0].cfitness)
newpopulation[i] = population[0];
else
{
for (j = 0; j < POPSIZE;j++)
if (p >= population[j].cfitness &&
p<population[j+1].cfitness)
newpopulation[i] = population[j+1];
}
}
/* once a new population is created, it back */
for (i = 0; i < POPSIZE; i++)
population[i] = newpopulation[i];
}
/***************************************************************/
/* Crossover selection: selects two parents that take part in */
/* the crossover. Implements a single point crossover */
/***************************************************************/
void crossover(void)
{
int i, mem, one;
int first = 0; /* count of the number of members chosen */
double x;
for (mem = 0; mem < POPSIZE; ++mem)
{
x = rand()%1000/1000.0;
if (x < PXOVER)
{
++first;
if (first % 2 == 0)
Xover(one, mem);
else
one = mem;
}
}
}
/**************************************************************/
/* Crossover: performs crossover of the two selected parents. */
/**************************************************************/
void Xover(int one, int two)
{
int i;
int point; /* crossover point */
/* select crossover point */
if(NVARS > 1)
{
if(NVARS == 2)
point = 1;
else
point = (rand() % (NVARS - 1)) + 1;
for (i = 0; i < point; i++)
swap(&population[one].gene[i], &population[two].gene[i]);
}
}
/*************************************************************/
/* Swap: A swap procere that helps in swapping 2 variables */
/*************************************************************/
void swap(double *x, double *y)
{
double temp;
temp = *x;
*x = *y;
*y = temp;
}
/**************************************************************/
/* Mutation: Random uniform mutation. A variable selected for */
/* mutation is replaced by a random value between lower and */
/* upper bounds of this variable */
/**************************************************************/
void mutate(void)
{
int i, j;
double lbound, hbound;
double x;
for (i = 0; i < POPSIZE; i++)
for (j = 0; j < NVARS; j++)
{
x = rand()%1000/1000.0;
if (x < PMUTATION)
{
/* find the bounds on the variable to be mutated */
lbound = population[i].lower[j];
hbound = population[i].upper[j];
population[i].gene[j] = randval(lbound, hbound);
}
}
}
/***************************************************************/
/* Report function: Reports progress of the simulation. Data */
/* mped into the output file are separated by commas */
/***************************************************************/
。。。。。
代碼太多 你到下面呢個網站看看吧
void main(void)
{
int i;
if ((galog = fopen("galog.txt","w"))==NULL)
{
exit(1);
}
generation = 0;
fprintf(galog, "\n generation best average standard \n");
fprintf(galog, " number value fitness deviation \n");
initialize();
evaluate();
keep_the_best();
while(generation<MAXGENS)
{
generation++;
select();
crossover();
mutate();
report();
evaluate();
elitist();
}
fprintf(galog,"\n\n Simulation completed\n");
fprintf(galog,"\n Best member: \n");
for (i = 0; i < NVARS; i++)
{
fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);
}
fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);
fclose(galog);
printf("Success\n");
}
Ⅱ 遺傳演算法 編程
染色體長度問題應該很容易解決,因為都是動態的分配內存,然後再用一個變數來記錄染色體有多長就可以了。不過這樣也僅限於編碼方式比較簡單的問題。實際中,對於不同的問題,有可能編碼方案截然不同,你能做到的就是讓你的演算法能夠在某一類問題上做到通用。例如,對所有採用二進制編碼的問題通用,或者對所有採用實數編碼的問題通用。
VBscript,java Script應該都可以寫遺傳演算法的。實際上只要這種語言可以產生隨機數,只要能夠處理數組,能夠進行循環,那麼就肯定可以寫遺傳演算法。另外,為什麼要vbscript和javascript配合呢?任何一種都可以了。
Ⅲ 如何用matlab遺傳演算法編程
有兩種方法,一種是用matlab自帶的遺傳演算法工具箱;還有一種是自己編寫遺傳演算法解決問題。第二種方法的話,網上可以找到很多遺傳演算法的matlab代碼,我也可以提供。第一種的話,有一定的局限性。
Ⅳ MATLAB中遺傳演算法編程中,二進制編碼如何處理實數變數
假如你想要編碼為x,設x的范圍是【min,max】,二進制編碼長度為10,那二進解碼方式是:x*(max-min)/1023,這個不用開始編碼,開始你可以用rand(n,10)產生n個樣本的隨機數,然後優化即可。
不是能把「數學模型中的目標函數和每一條約束函數分別編程Matlab里的M文件」,是你用遺傳演算法就必須要編進去,電腦怎麼知道往哪個方向優化是好的,要不把你郵箱留下,我給你發個尋求最大值的遺傳演算法。
Ⅳ 遺傳演算法的迭代次數是怎麼確定的,與什麼有關
1. 遺傳演算法簡介
遺傳演算法是用於解決最優化問題的一種搜索演算法,演算法的整體思路是建立在達爾文生物進化論「優勝劣汰」規律的基礎上。它將生物學中的基因編碼、染色體交叉、基因變異以及自然選擇等概念引入最優化問題的求解過程中,通過不斷的「種群進化」,最終得到問題的最優解。
2. 遺傳演算法實現步驟
在講下面幾個基於生物學提出的概念之前,首先我們需要理解為什麼需要在最優化問題的求解中引入生物學中的各種概念。
假設我們需要求一個函數的最大值,但這個函數異常復雜以至於無法套用一般化的公式,那麼就會想到:如果可以將所有可能的解代入方程,那麼函數最大值所對應的那個解就是問題的最優解。但是,對於較復雜的函數來說,其可能的解的個數的數量級是我們所無法想像的。因此,我們只好退而求其次,只代入部分解並在其中找到最優解。那麼這樣做的核心就在於如何設定演算法確定部分解並去逼近函數的最優解或者較好的局部最優解。
遺傳演算法就是為了解決上述問題而誕生的。假設函數值所對應的所有解是一個容量超級大的種群,而種群中的個體就是一個個解,接下去遺傳演算法的工作就是讓這個種群中的部分個體去不斷繁衍,在繁衍的過程中一方面會發生染色體交叉而產生新的個體。另一方面,基因變異也會有概率會發生並產生新的個體。接下去,只需要通過自然選擇的方式,淘汰質量差的個體,保留質量好的個體,並且讓這個繁衍的過程持續下去,那麼最後就有可能進化出最優或者較優的個體。這么看來原來最優化問題居然和遺傳變異是相通的,而且大自然早已掌握了這樣的機制,這著實令人興奮。為了將這種機制引入最優化問題並利用計算機求解,我們需要將上述提到的生物學概念轉化為計算機能夠理解的演算法機制。
下面介紹在計算機中這種遺傳變異的機制是如何實現的:
基因編碼與解碼:
在生物學中,交叉與變異能夠實現是得益於染色體上的基因,可以想像每個個體都是一串超級長的基因編碼,當兩個個體發生交叉時,兩條基因編碼就會發生交換,產生的新基因同時包含父親和母親的基因編碼。在交叉過程中或者完成後,某些基因點位又會因為各種因素發生突變,由此產生新的基因編碼。當然,發生交叉和變異之後的個體並不一定優於原個體,但這給了進化(產生更加優秀的個體)發生的可能。
因此,為了在計算機里實現交叉和變異,就需要對十進制的解進行編碼。對於計算機來說其最底層的語言是由二進制0、1構成的,而0、1就能夠被用來表示每個基因點位,大量的0、1就能夠表示一串基因編碼,因此我們可以用二進制對十進制數進行編碼,即將十進制的數映射到二進制上。但是我們並不關心如何將十進制轉換為二進制的數,因為計算機可以隨機生成大量的二進制串,我們只需要將辦法將二進制轉化為十進制就可以了。
二進制轉換為十進制實現方式:
假設,我們需要將二進制映射到以下范圍:
首先,將二進制串展開並通過計算式轉化為[0,1]范圍內的數字:
將[0,1]范圍內的數字映射到我們所需要的區間內:
交叉與變異:
在能夠用二進制串表示十進制數的基礎上,我們需要將交叉與變異引入演算法中。假設我們已經獲得兩條二進制串(基因編碼),一條作為父親,一條作為母親,那麼交叉指的就是用父方一半的二進制編碼與母方一半的二進制編碼組合成為一條新的二進制串(即新的基因)。變異則指的是在交叉完成產生子代的過程中,二進制串上某個數字發生了變異,由此產生新的二進制串。當然,交叉與變異並不是必然發生的,其需要滿足一定的概率條件。一般來說,交叉發生的概率較大,變異發生的概率較小。交叉是為了讓演算法朝著收斂的方向發展,而變異則是為了讓演算法有幾率跳出某種局部最優解。
自然選擇:
在成功將基因編碼和解碼以及交叉與變異引入演算法後,我們已經實現了讓演算法自動產生部分解並優化的機制。接下去,我們需要解決如何在演算法中實現自然選擇並將優秀的個體保留下來進而進化出更優秀的個體。
首先我們需要確定個體是否優秀,考慮先將其二進制串轉化為十進制數並代入最初定義的目標函數中,將函數值定義為適應度。在這里,假設我們要求的是最大值,則定義函數值越大,則其適應度越大。那是否在每一輪迭代過程中只需要按照適應度對個體進行排序並選出更加優秀的個體就可以了呢?事實上,自然選擇的過程中存在一個現象,並沒有說優秀的個體一定會被保留,而差勁的個體就一定被會被淘汰。自然選擇是一個概率事件,越適應環境則生存下去的概率越高,反之越低。為了遵循這樣的思想,我們可以根據之前定義的適應度的大小給定每個個體一定的生存概率,其適應度越高,則在篩選時被保留下來的概率也越高,反之越低。
那麼問題就來了,如何定義這種生存概率,一般來說,我們可以將個體適應度與全部個體適應度之和的比率作為生存概率。但我們在定義適應度時使用函數值進行定義的,但函數值是有可能為負的,但概率不能為負。因此,我們需要對函數值進行正數化處理,其處理方式如下:
定義適應度函數:
定義生存概率函數:
註:最後一項之所以加上0.0001是因為不能讓某個個體的生存概率變為0,這不符合自然選擇中包含的概率思想。
3. 遺傳算例
在這里以一個比較簡單的函數為例,可以直接判斷出函數的最小值為0,最優解為(0,0)
若利用遺傳演算法進行求解,設定交叉概率為0.8,變異概率為0.005,種群內個體數為2000,十進制數基因編碼長度為24,迭代次數為500次。
從遺傳演算法收斂的動態圖中可以發現,遺傳演算法現實生成了大量的解,並對這些解進行試錯,最終收斂到最大值,可以發現遺傳演算法的結果大致上與最優解無異,結果圖如下:
4. 遺傳演算法優缺點
優點:
1、 通過變異機制避免演算法陷入局部最優,搜索能力強
2、 引入自然選擇中的概率思想,個體的選擇具有隨機性
3、 可拓展性強,易於與其他演算法進行結合使用
缺點:
1、 遺傳演算法編程較為復雜,涉及到基因編碼與解碼
2、 演算法內包含的交叉率、變異率等參數的設定需要依靠經驗確定
3、 對於初始種群的優劣依賴性較強
Ⅵ MATLAB遺傳演算法編程(多目標優化)
多目標是通過分布性 和非劣解來進行評價的
Ⅶ matlab遺傳演算法編程求最大值的問題
(1)關於fitness value,你要自己定義一個函數,如你所說從25個x變數經過一系列運算得到y值 可以其作為fitness value
(2)由於x的取值是離散的 染色體不一定要是二進制 最簡單的做法是一個5進制的長為25的串
Ⅷ 《Java遺傳演算法編程》pdf下載在線閱讀全文,求百度網盤雲資源
《Java遺傳演算法編程》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1l6_14X1Yhcgv8kYwHqyY2g
簡介:本書簡單、直接地介紹了遺傳演算法,並且針對所討論的示例問題,給出了Java代碼的演算法實現。全書分為6章。第1章簡單介紹了人工智慧和生物進化的知識背景,這也是遺傳演算法的歷史知識背景。第2章給出了一個基本遺傳演算法的實現;第4章和第5章,分別針對機器人控制器、旅行商問題、排課問題展開分析和討論,並給出了演算法實現。在這些章的末尾,還給出了一些練習供讀者深入學習和實踐。第6章專門討論了各種演算法的優化問題。
Ⅸ 遺傳演算法編程,求指教
你好 你最後這個問題解決了嗎 我也是遇到了這個問題