Genetic Algorithm Primary

Genetic algorithm is an algorithm which imitate the law of natural selection.

The main step:

Step 1:      Initialization     (Set Max evolutionary algebra and Create new individuals randomly)

Step 2:      Individual evaluation (Evaluate the fitness of each individuals using a fitness function)

Step 3:      Selection (Pick the proper individuals according to fitness)

Step 4:      Crossover (The most important part of GA)

Step 5:    Mutation (Accelerating convergence of the optimal solution)

 

         Worth mentioning, in most function, GA has to be stochastic realization. For example, in selection part, the larger an individual’s fitness is, the greater the chance of an individual to survive instead of individuals which has a larger survival rate survive certainly.

         To realize the randomness, there lots of methods we can choose. A good way is roulette wheel selection. We can first figure out the survival rate of an individual like this:

 

And then, we produce a random number and find out which part of it. Implement code:

 

    Genome GenAlg:: GetChromoRoulette()  
      
    {  
      
        //产生一个0到人口总适应性评分总和之间的随机数.  
      
        //中m_dTotalFitness记录了整个种群的适应性分数总和)  
      
        double Slice = (random()) * totalFitness;  
      
        //这个基因将承载转盘所选出来的那个个体.  
      
        Genome TheChosenOne;  
      
        //累计适应性分数的和.  
      
        double FitnessSoFar = 0;  
      
        //遍历总人口里面的每一条染色体。  
      
        for (int i=0; i<popSize; ++i)  
      
        {  
      
            //累计适应性分数.  
      
            FitnessSoFar += vecPop[i].fitness;  
      
            //如果累计分数大于随机数,就选择此时的基因.  
      
            if (FitnessSoFar >= Slice)  
      
            {  
      
                TheChosenOne = vecPop[i];  
      
                break;  
      
            }  
      
        }  
      
        //返回转盘选出来的个体基因  
      
        return TheChosenOne;  
      
    }  

 

This weekend, I just learn a little of the GA, understanding the process of this algorithm. And take TSP problem as an example, simulating the process of GA roughly. Due to the lack of the main optimization algorithm, my GA code seem to be useless. My first GA code only reflect the idea of random, but not the idea of optimization and convergence. But my understanding of GA is deepen through this problem.

Here is my code:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<fstream>
#include<cmath>
#include<ctime>
using namespace std;
typedef long long LL;
/************************City Set************************/
string filename = "berlin52.txt";
#define runs 10
#define groupNum 10
#define cnt 52 //城市数量
const double pc = 0.65;//交配概率
const double mp = 0.35;//变异概率
/*********************************************************/
double edge[cnt][cnt];
double best_tsp = 1e7;
int trace[cnt];

struct City{
    double x, y;
}city[cnt];

struct Group{
    int cities[cnt];
    double tsp;
    double fit;    
}group[groupNum], groupt[groupNum];

void init(){
    int num = 0;
    ifstream fin(filename);
    while(fin>>num){
        fin>>city[num-1].x>>city[num-1].y;
        //cout<<num-1<<" "<<city[num-1].x<<" "<<city[num-1].y<<endl;
    }
    //构造邻接矩阵
    for(int i =0 ; i< cnt ; ++i){
        edge[i][i] = 0;
        for(int j =i+1 ; j< cnt ; ++j){
            edge[j][i] = edge[i][j] = sqrt((city[i].x-city[j].x)*(city[i].x-city[j].x) + (city[i].y-city[j].y)*(city[i].y-city[j].y));
        }
    }
    /*cout<<"邻接矩阵为"<<endl;
    for(int i=0 ; i<cnt ; ++i){
        for(int j =0 ; j<cnt ; ++j){
            cout<<edge[i][j]<<" ";
        }
        cout<<endl;
    }*/
}

void print(){
    for(int i =0 ; i<groupNum ;++i){
        cout<<"Group"<<i<<":";
        for(int j= 0 ; j<cnt ; ++j)    cout<<" "<<group[i].cities[j];
        cout<<endl;
    }
}

void pre_value(){
    srand(time(0));
    /***********************给每个种群初始化**************************/
    for(int i = 0 ; i<groupNum ; ++i){
        int j = 0; 
        for(int k = 0 ; k< cnt ; ++k){
            group[i].cities[k] = -1;
        }
        while( j<cnt ){
            int x = rand()%cnt ;
            if(group[i].cities[x] == -1){
                group[i].cities[x] = j;
                ++j;
            }
        }
    }
    /********************打印种群*****************************/
    cout<<"Initial Population:"<<endl;
    for(int i=0 ; i<groupNum ; ++i){
        cout<<"Group"<<i<<":";
        for(int j=0 ;j<cnt ; ++j){
            cout<<group[i].cities[j]<<" ";
        }
        cout<<endl;
    }
    //system("pause");
}

void fitness(){
    /*************************计算种群总路径*****************************/
    double sum_dis = 0;
    for(int i=0 ; i< groupNum ; ++i){
        group[i].tsp = 0;
        group[i].fit = 0;
    }
    for(int i =0 ; i<groupNum ; ++i){
        for(int j=0 ; j<cnt ; ++j){
            if(j == cnt -1){
                group[i].tsp += edge[group[i].cities[cnt-1]][group[i].cities[0]];
            }
            else group[i].tsp += edge[group[i].cities[j]][group[i].cities[j+1]];
        }
        sum_dis += group[i].tsp;
    }
    /*************************计算每个种群的存活几率***********************/
    double sum_fit = 0;
    for(int i=0 ; i<groupNum ; ++i){
        group[i].fit = 1 - group[i].tsp / sum_dis;
        sum_fit += group[i].fit;
    }
    for(int i=0 ; i<groupNum ;++i){
        group[i].fit = group[i].fit/sum_fit;
    }
    int best = 0; 
    for(int i= 0; i<groupNum ; ++i){
        if( group[i].tsp < group[best].tsp ){
            best = i;
        }
    }
    /************************************************************************/
    /*cout<<"当前代最好的种群是种群"<<best<<':'<<endl;
    for(int i=0; i<cnt ; ++i){
        cout<<group[best].cities[i]<<" ";
    }*/
    if( group[best].tsp < best_tsp){
        best_tsp = group[best].tsp;
        for(int i=0 ; i< cnt ; ++i){
            trace[i] = group[best].cities[i];
        }
    }
    //cout<<"TSP = "<<group[best].tsp<<endl;
    //system("pause");
}

void select(){
    int chosen[groupNum];
    /*********************轮盘法随机选择种群***************************/
    for(int i =0 ; i<groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        double fitSofar = 0;
        for(int j=0 ; j< groupNum ; ++j){
            fitSofar += group[j].fit;
            if(fitSofar > x ){
                chosen[i] = j;    break;
            }
        }
    }
    /*************************复制产生新一代种群*************************/
    for(int i=0 ; i<groupNum ; ++i){
        groupt[i] = group[i];
    }
    for(int i=0 ; i<groupNum ;++i){
        group[i] = groupt[ chosen[i] ];
    }
    /*********************************************************************/
    //cout<<"The new generation:"<<endl;
    //print();
    //system("pause");
}

void cross(){
    int t=0;
    int crossp[groupNum];
    memset(crossp, 0, sizeof(crossp));
    /*********************确定交配种群个数***********************/
    for(int i=0 ; i< groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        if( x<pc ){
            crossp[t++] = i;
        }
    }
    //t = t/2*2;  //保证t为偶数
    /************************开始交配**************************/
    for(int j=0 ; j+1<t ; j+=2){
        int temp1 = j, temp2 = j+1;
        int map1[cnt], map2[cnt];
        int point1, point2;
        point1 = rand()%cnt;    point2 = rand()%cnt;
        if(point2<point1)    swap(point1, point2);
        //两头直接交换
        for(int i=0 ; i<point1; ++i){
            swap(group[temp1].cities[i], group[temp2].cities[i]);
        }
        for(int i=point2+1 ; i<cnt; ++i){
            swap(group[temp1].cities[i], group[temp2].cities[i]);
        }
        //中间产生映射, 处理冲突
        memset(map1, 0, sizeof(map1));
        memset(map2, 0, sizeof(map2));
        for(int i=point1 ; i<=point2; ++i){
            map1[group[temp1].cities[i]] = group[temp2].cities[i];
            map2[group[temp2].cities[i]] = group[temp1].cities[i];
        }
        //处理temp1的冲突
        for(int k = 0 ; k < point1; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp1].cities[k] == group[temp1].cities[kk]){
                    group[temp1].cities[k] = map1[group[temp1].cities[kk]];
                    kk=point1-1;
                    //cout<<"kk = "<<kk<<" ";    system("pause");
                }
            }
        }
        for(int k = point2+1 ; k < cnt; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp1].cities[k] == group[temp1].cities[kk]){
                    group[temp1].cities[k] = map1[group[temp1].cities[kk]];
                    kk=point1-1;
                }
            }
        }
        //处理temp2的冲突
        for(int k = 0 ; k < point1; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp2].cities[k] == group[temp2].cities[kk]){
                    group[temp2].cities[k] = map2[group[temp2].cities[kk]];
                    kk=point1-1;
                }
            }
        }
        for(int k = point2+1 ; k < cnt; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp2].cities[k] == group[temp2].cities[kk]){
                    group[temp2].cities[k] = map2[group[temp2].cities[kk]];
                    kk=point1-1;
                }
            }
        }
    }
    //cout<<"After crossover:"<<endl;
    //print();
}

void mutate(){
    int mutatep[groupNum];
    int t=0;//变异个数
    srand(time(0));
    memset(mutatep, 0, sizeof(mutatep));
    for(int i=0 ; i<groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        if( x< mp){
            mutatep[t++] = i;
        }
    }
    //开始变异,即随机交换一对城市
    for(int i =0 ; i<t; ++i){
        int temp = mutatep[i];
        int point1 = rand()%cnt;
        int point2 = rand()%cnt;
        swap(group[temp].cities[point1], group[temp].cities[point2]);
    }

    //cout<<"After mutation:"<<endl;
    //print();
}


int main(){
    init();
    pre_value();
    int counter = 0;
    while(counter++ < runs){
        fitness();
        select();
        cross();
        mutate();
    }
    print();
    cout<<"Best tsp = "<<best_tsp<<endl;
    cout<<"Trace:"<<endl;
    for(int i=0 ; i<cnt ; ++i){
        cout<<trace[i]<<" ";
    }
    cout<<endl;
    system("pause");
    return 0;
}

 

转载于:https://www.cnblogs.com/topW2W/p/5297178.html

CREATE TABLE user ( user_id VARCHAR(36) PRIMARY KEY COMMENT 'UUID主键', username VARCHAR(50) UNIQUE NOT NULL COMMENT '用户名(学号/工号)', password VARCHAR(100) NOT NULL COMMENT '加密存储', role ENUM('student','teacher','admin') NOT NULL COMMENT '角色类型', interest_tags JSON COMMENT '兴趣标签(如["编程","生物"])[4](@ref)', ability_level JSON COMMENT '能力维度评分(如{"数学":85,"逻辑":78})[6](@ref)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE learning_resource ( resource_id VARCHAR(36) PRIMARY KEY, title VARCHAR(200) NOT NULL, type ENUM('video','document','quiz','project') NOT NULL COMMENT '资源类型', difficulty TINYINT CHECK (difficulty BETWEEN 1 AND 5) COMMENT '难度等级(1-5星)', subject_id VARCHAR(36) NOT NULL COMMENT '关联学科ID', prerequisite JSON COMMENT '前置知识点(如["向量运算","导数"])[3](@ref)', related_subjects JSON COMMENT '跨学科关联(如["生物信息学","数据科学"])[3](@ref)', duration INT COMMENT '预估学习时长(分钟)', FOREIGN KEY (subject_id) REFERENCES subject(subject_id) ); CREATE TABLE learning_path ( path_id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) NOT NULL, current_step INT DEFAULT 1 COMMENT '当前学习阶段', status ENUM('active','completed','paused') DEFAULT 'active', generated_by ENUM('genetic_algorithm','RL') NOT NULL COMMENT '生成算法类型[1](@ref)', version INT DEFAULT 1 COMMENT '路径版本号', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES user(user_id) ); -- 路径历史版本表(支持动态调整追溯) CREATE TABLE learning_path_history ( history_id VARCHAR(36) PRIMARY KEY, path_id VARCHAR(36) NOT NULL, path_structure JSON NOT NULL COMMENT '资源序列与依赖关系', adjustment_reason VARCHAR(500) COMMENT '如"知识点掌握度低于阈值"[6](@ref)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (path_id) REFERENCES learning_path(path_id) ); CREATE TABLE learning_progress ( progress_id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) NOT NULL, resource_id VARCHAR(36) NOT NULL, completion_rate DECIMAL(5,2) CHECK (completion_rate BETWEEN 0 AND 100), mastery_score DECIMAL(3,2) COMMENT '知识点掌握度(0-1)[6](@ref)', last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP, assessment_result JSON COMMENT '评估指标(如{"正确率":85,"耗时":120s})[8](@ref)', FOREIGN KEY (user_id) REFERENCES user(user_id), FOREIGN KEY (resource_id) REFERENCES learning_resource(resource_id) ); -- 知识点掌握度动态更新表(支持学习分析) CREATE TABLE knowledge_mastery ( user_id VARCHAR(36), knowledge_node VARCHAR(50) COMMENT '知识点唯一标识', p_current DECIMAL(3,2) COMMENT '当前掌握度[6](@ref)', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, knowledge_node) ); CREATE TABLE subject_relation ( relation_id VARCHAR(36) PRIMARY KEY, source_subject VARCHAR(50) NOT NULL COMMENT '如"计算机科学"', target_subject VARCHAR(50) NOT NULL COMMENT '如"分子生物学"', relation_type ENUM('prerequisite','complementary','parallel') NOT NULL, weight DECIMAL(3,2) COMMENT '关联强度(基于PageRank算法)[3](@ref)' ); CREATE TABLE student_profile ( profile_id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) UNIQUE NOT NULL, learning_style ENUM('visual','auditory','kinesthetic') COMMENT '学习风格[7](@ref)', cognitive_level TINYINT COMMENT '认知复杂度(1-5级)[3](@ref)', error_pattern JSON COMMENT '高频错误模式(FP-Growth挖掘结果)[6](@ref)', FOREIGN KEY (user_id) REFERENCES user(user_id) ); CREATE TABLE report ( report_id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) NOT NULL, metrics JSON COMMENT '如{"学习时长":1200,"知识点覆盖率":78%}', comparison_data JSON COMMENT '同群体对比分位数[7](@ref)', generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES user(user_id) );
05-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值