遗传算法 01背包问题 C++

#include <iostream>
//#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>



using namespace std;

const int PACK_MAX_W = 80;                  //背包最大承受重量
const int PACK_MAX_V = 75;                  //背包最大承受容积
const int NUM = 32;                         //物品数
const int MAX_GENERATION = 100;             //遗传最大代数
const int PS = 500;                         //种群规模
const float PC = 0.8;                       //交叉率
const float PV = 0.1;                      //变异率


const int zl[NUM]={22,15,4,5,10,19,21,20,8,13,2,3,3,17,12,5,12,4,1,21,14,23,17,15,20,22,25,0,22,15,25,13};
const int tj[NUM]={11,22,12,21,21,13,1,10,13,8,6,25,13,27,12,23,12,24,23,11,6,24,28,10,20,13,25,23,5,26,30,15};
const int value[NUM]={8,9,15,6,16,9,1,4,14,9,3,7,12,4,15,5,18,5,15,4,6,2,12,14,11,9,13,13,14,13,19,4};

//随机产生01
int pp(){
    float p;
    p = rand() % 1000 / 1000.0;
    if(p < 0.8)
        {//cout<<0<<" ";
        return 0;}
    else
        {//cout<<1<<" ";
        return 1;}
}
//个体类
class Entity{
public:
    int fit;
    int sum_w;
    int sum_v;
    int sum_val;
    int gene[NUM];
    int _count;

    Entity(){
    fit = 0;
    sum_v = 0;
    sum_w = 0;
    sum_val = 0;
    int i;
    for(i = 0;i < NUM;i++)
        gene[i] = 0;
    }

};

//遗传算法类
class GA{

private:

        Entity zq[PS];                          //种群
        Entity max_single;                      //最优个体

public:
        //读取物品的价值体积重量
        //void readData();
        //初始化种群
        void Init();
        //计算个体价值重量重量
        int Cal_SingleValue(int row);

        int Cal_SingleW(int row);

        int Cal_SingleV(int row);
        //计算个体适应度
        void Cal_Fitness();
        //计算价值最大个体
        void Cal_Maxval_Single(int _generation);
        //选择
        void Select();
        //是否交叉
        bool IsCross() {  return ( ( rand() % 1000 / 1000.0 ) <= PC ); }
        //交叉
        void Cross();
        //是否变异
        bool IsVariation() {  return ( ( rand() % 1000 / 1000.0 ) <= PV ); }
        //变异
        void Variation();
        //进行遗传,每五代几率变异
        void Run(){

            int i;
            //readData();
            Init();
            for(i = 0; i < MAX_GENERATION; i++){
                Cal_Fitness();
                Cal_Maxval_Single(i);
                Select();
                Cross();
                if(i % 5 == 0 && i != 0){
                    Variation();
                }
            }
            Cal_Fitness();
            Cal_Maxval_Single(MAX_GENERATION);
            cout<<"The best value is:"<<max_single.fit<<endl;
            cout<<"The best entity's gene is:"<<endl;
            for(int i = 0;i < NUM;i++){
                cout<<max_single.gene[i];
                if(i!=NUM-1)
                    cout<<" ";
            }

            cout<<endl<<"The best entity is in the "<<max_single._count<<" generation."<<endl;

        }
};
/*
void GA::readData(){
    ifstream fin;
    fin.open("input.txt");
    if(!fin)
        cout<<"error"<<endl;
    int n,i;
            //fin>>n;PACK_MAX_V = n;
            //fin>>n;PACK_MAX_W= n;
            //fin>>n;NUM = n;
    for(i = 0;i < NUM;i++){
        fin>>n;
        value[i] = n;
    }
    for(i = 0;i < NUM;i++){
        fin>>n;
        tj[i] = n;
    }
    for(i = 0;i < NUM;i++){
        fin>>n;
        zl[i] = n;
    }

    //for(i=0;i<NUM;i++){
    //    cout<<value[i]<<" "<<tj[i]<<" "<<zl[i]<<endl;
    //}

}
*/


void GA::Init(){
    int i,j,wsum,vsum;
    for(i = 0;i < PS;i++){
        wsum = 0;
        vsum = 0;
        for(j = 0;j < NUM;j++){
            zq[i].gene[j] = pp();
            wsum += zq[i].gene[j]*zl[j];
            vsum += zq[i].gene[j]*tj[j];
            }
        if(wsum > PACK_MAX_W||vsum > PACK_MAX_V)    //产生符合条件的个体
            i--;
    }
/*
    cout<<"Init:"<<endl;
    for (i = 0;i < PS;i++){
        for (j = 0;j < NUM;j++)
            cout<<zq[i].gene[j]<<" ";
        cout<<endl;
    }
*/
}

int GA::Cal_SingleValue(int row){
    int j,valuesum = 0;
    for(j = 0;j < NUM;j++){
        valuesum += zq[row].gene[j]*value[j];
    }
    zq[row].sum_val = valuesum;
    return valuesum;
}

int GA::Cal_SingleW(int row){
    int j,wsum = 0;
    for(j = 0;j < NUM;j++){
        wsum += zq[row].gene[j]*zl[j];
    }
    zq[row].sum_w = wsum;
    return wsum;
}

int GA::Cal_SingleV(int row){
    int j,vsum = 0;
    for(j = 0;j < 32;j++){
        vsum += zq[row].gene[j]*tj[j];
    }
    zq[row].sum_v = vsum;
    return vsum;
}

void GA::Cal_Fitness(){
    int i,w,v,val;
    for(i = 0; i < PS; i++) {
        w = Cal_SingleW(i);
        v = Cal_SingleV(i);
        val = Cal_SingleValue(i);
        if(w > PACK_MAX_W || v > PACK_MAX_V) { zq[i].fit = 0; continue; }
        zq[i].fit = val;
        //cout<<zq[i].fit<<endl;
        }

}

void GA::Cal_Maxval_Single(int _generation){
    int i,maxval = zq[0].fit,id = 0;
    for(i = 0;i < PS;i++)
        if(maxval < zq[i].fit){
            maxval = zq[i].fit;
            id = i;
        }
    if(maxval > max_single.fit){
        max_single = zq[id];
        max_single._count = _generation;
    }
}

void GA::Select(){

    int fit_sum = 0,i,j;
    float rand_rate,cur_rate;
    float selected_rate[PS];
    Entity new_zq[PS];

    for(i = 0;i < PS; i++){
        fit_sum += zq[i].fit;
    }
    //使用轮赌法进行选择
    selected_rate[0] = float(zq[0].fit) / fit_sum;

    for(i = 1; i < PS; i++){
        cur_rate = selected_rate[i-1] + float(zq[i].fit) / fit_sum;
        selected_rate[i] = cur_rate;
    }

    for(i = 0; i < PS; i++) {
        rand_rate = ( rand() % 1000 / 1000.0 );
        for (j = 0; j < PS; j++) {
            if(rand_rate <= selected_rate[j]) {
                new_zq[i] = zq[j];
                break;
            }
        }
    }
    for(i = 0;i < PS;i++){
        zq[i]= new_zq[i];
        //cout<<zq[i].fit<<endl;
    }

}

void GA::Cross(){
    int i,j;
    for(i = 0;i < PS - 1;i += 2){
        Entity en1 = zq[i];
        Entity en2 = zq[i + 1];

        for(j = 0;j < NUM; j++){
            if(IsCross()){
                int tmp = en1.gene[j];
                en1.gene[j] = en2.gene[j];
                en2.gene[j] = tmp;
            }
        }
        zq[i]=en1;
        zq[i+1]=en2;
    }
}

void GA::Variation(){
    int i,j;
    for(i = 0;i < PS;i++){
        if(IsVariation()){
            for (j = 0;j < NUM;j++){
                if(IsVariation()){
                    zq[i].gene[j] = zq[i].gene[j] ? 0 : 1;
                }
            }
        }
    }
}

int main(){
    srand(time(NULL));
    GA temp;
    temp.Run();
    return 0;
}

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/mrzzzzk/article/details/78408247
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞