遗传算法

// GeneticAlgorithm.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <stdio.h>
#include <tchar.h>
#include <algorithm>
#include <stdlib.h>
#include <time.h>

#define N 20

using namespace std;

unsigned char DNAs[N];
unsigned char tDNA[N];
double values[N];
int selval[N];

unsigned char mask[] = { 0,1,3,7,15,31,63,127,255 };

int dnacnt;

//获取适应度(函数值)
//函数http://www.wolframalpha.com/input/?i=y%3D-(x-140)%5E2*(x-140-120)*(1.25*(x-140)%2B180)%2F1000000%2B10
double GetValue(unsigned char v)
{
	double x = v;
	x -= 140;
	double ans=-x*x*(x-120)*(1.25*x+180)/1000000+10;
	return ans;
}

//单点交叉
void Crossover(int a, int b)
{
	int pos = rand()%7+1;
	unsigned char a1 =( tDNA[a] >> pos)&mask[8-pos];
	unsigned char a2 = tDNA[a] & mask[pos];
	unsigned char b1 = (tDNA[b] >> pos)&mask[8 - pos];
	unsigned char b2 = tDNA[b] & mask[pos];
	DNAs[dnacnt++] = (a1 << pos) | b2;
	DNAs[dnacnt++] = (b1 << pos) | a2;
}

//随机突变(翻转一位因为这个比较好写=_=)
void Mutation(int a)
{
	int pos = rand() % 8;
	DNAs[a] ^= (1 << pos);
}


int getid(int a)
{
	for (int i = 0; i < N; i++)
	{
		if (selval[i] > a)
			return i;
	}
	return 0;
}

int main()
{
	double sum;

	//Initialize
	srand((int)time(0));
	for (int i = 0; i < N; i++)
	{
		DNAs[i] = rand() % 256;
		printf("[%02d]:%d\n", i, DNAs[i]);
	}
	//开搞
	for (int gen = 0; gen < 10; gen++)
	{
		printf("Generation %d:\n", gen);
		for (int i = 0; i < N; i++)
		{
			printf("[%03d:%4d]\t", i, DNAs[i]);
			if ((i + 1) % 5 == 0)
				printf("\n");
		}
		sum = 0;
		//计算适应度
		printf("calcing values\n");
		for (int i = 0; i < N; i++)
		{
			values[i] = GetValue(DNAs[i]);
			printf("%03d:%6.02lf\t", i, values[i]);			
			//values[i] *= values[i];
			if ((i+1) % 5 == 0)
			{
				printf("\n");
			}
		}
		printf("\n");
		//选择,暴力淘汰掉值最小的selcnt个
		printf("selecting\n");
		int selcnt = N / 3;
		for (int i = 0; i < selcnt; i++)
		{
			double min = 9999;
			int minid = 0;
			for (int j = 0; j < N; j++)
			{
				if (values[j] > 0 && values[j] < min)
				{
					min = values[j];
					minid = j;
				}
			}
			values[minid] = -1;
			//printf("Exclude %d\n", minid);
		}
		//计算比例
		for (int i = 0; i < N; i++)
		{
			if (values[i] > 0)
				sum += values[i];
		}
		for (int i = 0; i < N; i++)
		{
			if (values[i] > 0)
			{
				selval[i] = (int)(values[i] / sum * 1000000);
				if (i != 0)
					selval[i] += selval[i - 1];
			}
			else
			{
				if (i != 0)
					selval[i] = selval[i - 1];
				else
				{
					selval[i] = 0;
				}
			}
			tDNA[i] = DNAs[i];
			//printf("sv:%d:%d\n", i, selval[i]);
		}
		//随机交叉,适应度高的有更大概率参与交叉
		printf("crossovering\n");
		
		for (dnacnt = 0; dnacnt < N;)
		{
			int a = rand() % 1000*1000+rand();
			int b = rand() % 1000 * 1000 + rand();
			//printf("{%d:%d}", a, b);
			a = getid(a);
			b = getid(b);
			Crossover(a, b);
			printf("[%03d:%03d]\t",a,b);
			if ((dnacnt + 1) % 5 == 0)
			{
				printf("\n");
			}
		}
		printf("\n");
		//随机突变,不清楚有没有用
		printf("Mutating\n");
		for (int i = 0; i < N; i++)
		{
			if (rand() % 20 == 7)
			{
				Mutation(i);
				printf("[%03d:%03d]\n", i, DNAs[i]);
			}
		}
		
	}
	printf("Result:\n");
	for (int i = 0; i < N; i++)
	{
		printf("[%03d:%4d:%6.02lf]\t", i, DNAs[i],GetValue(DNAs[i]));
		if ((i + 1) % 5 == 0)
			printf("\n");
	}
	getchar();
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值