天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 73|回复: 0

遗传算法三种交叉算子(OX、PMX、CX)

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <bits/stdc++.h>

#include <algorithm>
using namespace std;
unsigned seed = (unsigned)time(NULL);

void Chrom_out(int r[],int u)//染色体输出函数
{
    int l;
    for (l = 0; l < u-1; l++)
    {
        cout << r[l] << "--";
    }
    cout << r[u-1] << endl;
}

/*************OX程序*************/
bool check_point(int p[], int m, int x1, int x2)//检测节点是否再某条染色体中
{
    int i;
    for (i = x1; i <= x2; i++)
    {
        if (m == p[i])
            return true;
    }
    return false;
}

void GA_OX(int f1[],int f2[])       //这里只产生了一个子代
{
    int i;
    int x1, x2;
    int s[10] = { 0 };
    srand(seed);
    x1 = rand() % 10;
    srand(seed);
    x2 = rand() % (9 - x1 + 1) + x1;
    for (i = x1; i <= x2; i++)
    {
        s[i] = f1[i];
    }
    int t = (x2 + 1) % 10;
    int j = 0;
    for (i = t; i < t + 10; i++)
    {
        if (check_point(s, f2[i % 10], x1, x2) == false)
        {
            j += 1;
            s[(x2 + j) % 10] = f2[i % 10];
        }
    }
    cout << "交叉位置:" << x1 << "," << x2 << endl;
    cout << "OX结果:" << endl;
    Chrom_out(s, 10);
}
/*************OX程序*************/

/*************PMX程序*************/
int  judgment(int y,int x1,int x2,int s[])//判断节点是否在某染色体中,如果在则返回对应指数,否则返回一个较大的值(例如:100)
{
    int n;
    for (n = x1; n <= x2; n++)
    {
        if (y == s[n])
            return n;
    }
    return 100;
}

void GA_PMX(int f1[], int f2[])
{
    int i, j;
    int x1, x2;
    int s1[10], s2[10];
    int trans_1[10] = { 0 }, trans_2[10] = { 0 };
    for (i = 0; i <= 9; i++)//复制到子代,等待后续交叉操作
    {
        s1[i] = f1[i];
        s2[i] = f2[i];
    }
    srand(seed);
    x1 = rand() % 9;
    srand(seed);
    x2 = rand() % (9 - x1) + x1 + 1;//截取交叉片段

    int status;
    int t = 0;
   
    for (i = x1; i <= x2; i++)
    {
        status = judgment(s1[i], x1, x2, s2);
        if (status==100)
        {
            trans_1[t] = s1[i];
            j = i;
            bool flag = true;
            do
            {
                status = judgment(s2[j], x1, x2, s1);
                if (status == 100)
                {
                    trans_2[t] = s2[j]; t = t + 1; break;
                }
                else
                    j = status;
            } while (flag);
        }   
    }
    int temp;
    for (j = 0; j < t; j++)
    {
        for (i = 0; i <= 9; i++)
        {
            if (s1[i] == trans_2[j])
            {
                status = judgment(trans_1[j], 0, 9, s2);
                temp = s1[i];
                s1[i] = s2[status];
                s2[status] = temp; break;
            }
        }
    }

    for (i = x1; i <= x2; i++)
    {
        s1[i] = f2[i];
        s2[i] = f1[i];
    }
    cout << "交叉位置:" << x1 << "," << x2 << endl;
    cout << "PMX结果:" << endl;
    Chrom_out(s1, 10);
    Chrom_out(s2, 10);
}
/*************PMX程序*************/

/*************CX程序*************/
int  find_position(int y, int m, int s[])//找出节点在某染色体的位置并返回
{
    int n;
    for (n = 0; n <= m; n++)
    {
        if (y == s[n])
            return n;
    }
}

void GA_CX(int f1[], int f2[])
{
    int h, k;
    int s1[10] = { 0 }, s2[10] = { 0 };
    int temp[10] = { 0 };
    int cycle_position[10][11] = { 0 };//记录环的各节点的位置,cycle_position[cycle_num][10]:记录环中节点数目
    int cycle_num = 0;//记录环的个数
    int position_num;
    int c;
    bool sign;
    for (k = 0; k <= 9; k++)//复制到子代,等待后续交叉操作
    {
        s1[k] = f1[k];
        s2[k] = f2[k];
    }
    for (k = 0; k <= 9; k++)
    {
        sign = true;
        for (h = 0; h <= 9; h++)//判断目前检测的节点是否已经检测过,若没有被检测过则找到该节点所在的环
        {
            if (s1[k] == temp[h])
                sign = false;
        }
        if (sign)
        {
            position_num = 0;//记录回环中节点数
            c = k;//记录目前检测的节点的位置
            cycle_position[cycle_num][0] = k;
            temp[0] = s1[c];
            bool flag = true;
            do
            {
                if (s2[c] == s1[k])
                {
                    cycle_position[cycle_num][10] = position_num;
                    cycle_num += 1;
                    break;
                }
                else
                {
                    position_num += 1;
                    temp[position_num] = s2[c];
                    cycle_position[cycle_num][position_num]= find_position(s2[c], 10, s1);
                    c = cycle_position[cycle_num][position_num];
                }
            } while (flag);
        }
    }
    int z;
    int p;
    int trans;
    srand(seed);
    p = rand() % cycle_num;
    cout << "交叉回路:" << endl;
    for (z = 0; z <= cycle_position[p][10]; z++)//染色体交叉,并输出完成交换的环
    {
        cout << s1[cycle_position[p][z]] << "<-->" << s2[cycle_position[p][z]] << "   ";
        trans = s1[cycle_position[p][z]];
        s1[cycle_position[p][z]] = s2[cycle_position[p][z]];
        s2[cycle_position[p][z]] = trans;
    }

    cout << endl << "CX结果:" << endl;        //结果输出
    Chrom_out(s1, 10);
    Chrom_out(s2, 10);
}
/*************CX程序*************/

int main()
{
    int F_1[10] = { 1,5,8,6,9,3,4,7,2,10 };
    int F_2[10] = { 10,5,9,4,3,2,6,7,1,8 };//示例染色体
    cout << "父代染色体:" << endl;
    Chrom_out(F_1, 10);
    Chrom_out(F_2, 10);

    /*函数调用*/
    GA_OX(F_1, F_2);
    GA_PMX(F_1, F_2);
    GA_CX(F_1, F_2);

    return 0;
}

 

 

 

 

遗传算法三种交叉算子(OX、PMX、CX)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 10:37 , Processed in 0.130395 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表