人工智能 基於遺傳算法的隨機優化搜索的應用舉例

題目:利用遺傳算法求解區間[0,31]上的二次函數y=x*x的最大值。

//題目: 利用遺傳算法求解區間[0, 31]上的二次函數y = x*x的最大值
 
#include
#include
#include
#include
using namespace std;
 
int N = 4;//種羣規模
int T = 100;//最大換代數
double Pc = 0.4;//交叉率
double Pm = 0.01;//變異率
int option = 0;
 
int t;//代數計數器
 
bool flag = true;//標記是否是第一次計算結果
 
struct solution{
    int num;    //十進制數
    char b[5];  //5位二進制數編碼染色體
    int f;      //適應度
    double p;   //選擇概率
    double q;   //積累概率
}*s, *next;
 
void showCondition(){
    cout << "種羣規模: " << N << endl;
    cout << "最大換代數: " << T << endl;
    cout << "交叉率: " << Pc << endl;
    cout << "變異率: " << Pm << endl << endl;
    if(!flag)
        system("pause");
}
 
//交換字符
void swap(char *a, char *b){
    char c = *a;
    *a = *b;
    *b = c;
}
 
//十進制轉換爲二進制
void DtoB(int n, char str[]){
    int tmp, i = 0;
    memset(str, '0', 5);
    while(n){
        tmp = n % 2;
        str[i] = (char)tmp;
        n /= 2;
        i++;
    }
 
    //翻轉
    swap(&str[0], &str[4]);
    swap(&str[1], &str[3]);
}
 
//生成初始種羣
void init(){
    t = 1;
    srand((unsigned)time(0));
    if(flag){
        s = new struct solution[N];
        next = new struct solution[N];
        flag = false;
    }
    else{
        delete [] s;
        delete [] next;
        s = new struct solution[N];
        next = new struct solution[N];
    }
 
    for(int i = 0; i < N; i++){
        s[i].num = rand() % 32;
        DtoB(s[i].num, s[i].b);
        s[i].f = s[i].num * s[i].num;
    }
 
    int sumf = 0;//適應度總和
    for(int i = 0; i < N; i++)
        sumf += s[i].f;
 
    double sumq = 0.0;//積累概率總和
    for(int i = 0; i < N; i++){
        s[i].p = (double)s[i].f / sumf;
        sumq += s[i].p;
        s[i].q = sumq;
    }
}
 
//產生0~1之間的隨機數
double randf()
{
    return (double)(rand() % 1001) * 0.001;
}
 
//選擇-複製
void SelectNCopy(){
    double r;
    struct solution tmp[N];
    for(int i = 0; i < N; i++){
        r = randf();
        if(r < s[0].q)
            tmp[i] = s[0];
        else{
            int j;
            for(j = 1; j < N; j++){
                            if(r > s[j-1].q && r < s[j].q)
                    break;
            }
            tmp[i] = s[j];
        }
    }
    for(int i = 0; i < N; i++)
        next[i] = tmp[i];
}
 
//交叉
void mate(){
    int a = 0, b = 0;
    while(a == b){
        srand((unsigned)time(0));
        a = rand() % N;
        b = rand() % N;
    }
    int cb = rand() % 5;//交換的位數
    char ctmp;
    for(int i = 0; i < cb; i++)   {
    //  swap(&s[a].b[4 - i], &next[b].num[4 - i]);
        ctmp = s[a].b[4 - i];
        next[a].b[4 - i] = next[b].b[4 - i];
        next[b].b[4 - i] = ctmp;
    }
}
 
//變異
void variate(){
    int bits = int(5 * Pm);
    if(bits < 1)
        return ;
    else{
        int tmp;
        srand((unsigned)time(0));
        for(int i = 0; i < N; i++){
            tmp = rand() % 5;
            if(next[i].b[tmp] == '0')
                next[i].b[tmp] = '1';
            else
                next[i].b[tmp] = '0';
        }
    }
    return ;
}
 
//返回適應度最大的解
struct solution maxf(struct solution ss[]){
    struct solution temp = ss[0];
    for(int i = 1; i < N; i++)       if(ss[i].f > temp.f)
             temp = ss[i];
    return temp;
}
 
//進化,適者生存
void evolve(){
    struct solution cm, nm;// cm:當前代適應度最大值,nm下一代適應度最大值
    cm = maxf(s) ;
    nm = maxf(next);
    if(nm.f > cm.f)
        for(int i = 0; i < N; i++)
            s[i] = next[i];
}
 
//用遺傳算法求解答案
void solve(){
    int mt;//交叉次數
 
    while(t         SelectNCopy();
        mt = (int)(5 * Pc) / 2;
        for(int i = 0; i < mt; i++)
            mate();
        variate();
        evolve();
        t++;
    }
    struct solution max = s[0];
    for(int i = 0; i < N; i++)       if(s[i].f > max.f)
            max = s[i];
    printf("求得的解是:%d\n", max.num);
    return ;
}
 
// 計算答案
void calculate(){
    init();
    solve();
}
 
void menu(){
    cout << "利用遺傳算法求解區間[0, 31]上的二次函數y = x*x的最大值\n" << endl;
    cout << "初始狀態:" << endl;
    showCondition();
 
    cout << endl;
    while(true){
        cout << "1>>>計算結果" << endl;
        cout << "2>>>設置種羣規模" << endl;
        cout << "3>>>設置最大換代數" << endl;
        cout << "4>>>設置交叉率" << endl;
        cout << "5>>>設置變異率" << endl;
        cout << "6>>>顯示各種參數" << endl;
        cout << "0>>>退出程序\n" << endl;
                cin >> option;
 
        switch(option){
            case 1:calculate();break;
            case 2:
                    cout << "請輸入新的種羣規模值: ";
                                cin >> N;break;
            case 3:
                    cout << "請輸入新的最大換代數: ";
                                cin >> T;break;
            case 4:
                cout << "請輸入新的交叉率: ";
                                cin >> Pc;break;
            case 5:
                cout << "請輸入新的變異率: ";
                                cin >> Pm;break;
            case 6:showCondition();break;
            case 0:exit(0);break;
            default:cout << "選擇錯誤!請重新選擇!\n" << endl;break;
        }
    }
}
 
int main(){
    menu();
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章