⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chrom.cpp

📁 利用一个较为成熟的遗传算法基础类库(作者:刘康)
💻 CPP
字号:
//头文件:		Chrom.hpp
//目的:			为染色体提供基类
//语言:			VC++ 6.0
//时间:			1999年6月~2000年1月
//作者:			刘康
//环境:			Win32
//////////////////////////////////////////////////////////////////////

#include <stdlib.h>
#include <iostream.h>
#include <time.h>
#include <math.h>
#include "chrom.hpp"

//染色体初始化种子初始化
unsigned Chromosome::Seed = 0;

int Chromosome::totalCrossNum = 0;
int Chromosome::totalMutaNum = 0;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//构造函数
Chromosome::Chromosome()
{
	GeneLen = 0;
	Gene = NULL;
	geneStr = NULL;
}
Chromosome::Chromosome(int l)
{
	GeneLen = l;
	geneStr = new char[GeneLen+1];
	Init();
}

Chromosome::Chromosome(int l, int ones)
{
	GeneLen = l;
	geneStr = new char[GeneLen+1];
	Init(ones);
	fixedOne=true;
}

Chromosome::Chromosome(const Chromosome &c)
{
	ChromNum = c.ChromNum;
	GeneLen = c.GeneLen;
	Gene = new OneChmType[ChromNum];
	geneStr = new char[GeneLen+1];
	for(int i=0; i<ChromNum; i++)
		Gene[i] = c.Gene[i];
}

//析构函数
Chromosome::~Chromosome()
{
	if(Gene) delete []Gene;
	if(geneStr) delete[]geneStr;
}

/////////////////////////////////////////////////////////////////////
//私有函数
/////////////////////////////////////////////////////////////////////

//染色体初始化
void Chromosome::Init()
{
	ChromNum = GeneLen/(sizeof(OneChmType)*8)+1;
	Gene = new OneChmType[ChromNum];
	for(int i=0; i<ChromNum; i++)	Gene[i] ^= Gene[i];
	if(!Seed) Seed = (unsigned)time(NULL);
	srand(Seed);
	Seed = Seed+(unsigned)time(NULL);
	for(i=0; i<GeneLen; i++)
	{
		int cNum = i/(sizeof(OneChmType)*8);
		if(rand()>=RAND_MAX/2) 
		{
			Gene[cNum] <<= 1;
			Gene[cNum] |= 0x1; //set 1
		}
		else Gene[cNum] <<= 1; //set 0
	}
}

//染色体初始化,可设定1的个数
void Chromosome::Init(int ones)		
{
	ChromNum = GeneLen/(sizeof(OneChmType)*8)+1;
	Gene = new OneChmType[ChromNum];
	for(int i=0; i<ChromNum; i++)	Gene[i] ^= Gene[i]; //set 0 to all
	if(!Seed) Seed = (unsigned)time(NULL);
	srand(Seed);
	Seed = Seed+(unsigned)time(NULL);

	//设置指定个数的1
	int pos,pos_num,pos_bit;
	for(i=0; i<ones;)
	{
		pos=(int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);
		pos_num=pos/(sizeof(OneChmType)*8);
		pos_bit=pos-pos_num*(sizeof(OneChmType)*8);	

 		if(Gene[pos_num]&(0x01<<pos_bit)) continue;

		Gene[pos_num]|=(0x01<<pos_bit); //set 1
		i++;
	}
}

/////////////////////////////////////////////////////////////////////
//公有函数
/////////////////////////////////////////////////////////////////////

//设置染色体长度
void Chromosome::SetLen(int l)
{
	if(Gene) delete []Gene;
	GeneLen = l;
	if(geneStr) delete []geneStr;
	geneStr = new char[GeneLen+1];
	Init();
}

//设置染色体长度和1的个数
void Chromosome::SetLen(int l, int ones)
{
	if(Gene) delete []Gene;
	GeneLen = l;
	if(geneStr) delete []geneStr;
	geneStr = new char[GeneLen+1];
	Init(ones);
}

//返回字符串形式基因
/*
......
7,6,5,4
3,2,1,0
*/
const char* Chromosome::GetGeneStr()
{
	for(int i=0; i<GeneLen; i++)
	{
		int cNum = i/(sizeof(OneChmType)*8);
		int bit = i-cNum*(sizeof(OneChmType)*8);
		__int64 tmp = 0x1;
		tmp <<= bit;
		if(Gene[cNum] & tmp) geneStr[GeneLen-1-i] = '1';
		else geneStr[GeneLen-1-i] = '0';
	}
	geneStr[GeneLen] = '\0';
	return geneStr;
}

//返回i1位到i2位的整型值,包含i1,i2位
unsigned __int64 Chromosome::GetInt(int i1, int i2)
{
	if((i2-i1)<0 || (i2-i1)>=64 || i1<1) return -1;
	unsigned __int64 tmp=0;
	for(int i=i2-1; i>=i1-1; i--)
	{
		int cNum = i/(sizeof(OneChmType)*8);		//i位所在组
		int bits = i-cNum*(sizeof(OneChmType)*8);	//组内偏移
		OneChmType bit = (0x1<<bits);
		if(Gene[cNum]&bit)
		{
			tmp <<= 1;
			tmp |= 0x1;
		}
		else
			tmp <<= 1;
	}
	return tmp;
}

//=号重载函数
Chromosome& Chromosome::operator = (const Chromosome &c)
{
	if(Gene) delete []Gene;
	GeneLen = c.GeneLen;
	ChromNum = c.ChromNum;
	Gene = new OneChmType[ChromNum];
	for(int i=0; i<ChromNum; i++) Gene[i] = c.Gene[i];
	return *this;
}

//==号重载
bool Chromosome::operator == (const Chromosome &c)
{
	if(GeneLen!=c.GeneLen) return false;
	for(int i=0; i<ChromNum; i++)
		if(Gene[i] != c.Gene[i]) return false;
	return true;
}

//位变异函数
Chromosome Chromosome::Mutation(double prob)
{
	Chromosome temp(*this);
	if(fixedOne){//保持1的个数不变
		for(int i=0; i<GeneLen; i++)
		{
			int cNum = i/(sizeof(OneChmType)*8);		//所在组
			int bit = i-cNum*(sizeof(OneChmType)*8);	//组内偏移
			OneChmType bits = (0x1<<bit);
			if(((double)rand()/RAND_MAX)<prob){//需要变异
				int one,two;
				int one_num,two_num,one_bit,two_bit;
				one=i;
				one_num=one/(sizeof(OneChmType)*8);
				one_bit=one-one_num*(sizeof(OneChmType)*8);

				two=one;
				while(++two<GeneLen){
					two_num=two/(sizeof(OneChmType)*8);
					two_bit=two-two_num*(sizeof(OneChmType)*8);
					if(  (((temp.Gene[one_num]>>one_bit)^(temp.Gene[two_num]>>two_bit))&0x01)==1  )
						break;
				}
				
				if(two<GeneLen){//一次变异两位,保持1的个数不变
					OneChmType bits = (0x1<<one_bit);
					temp.Gene[one_num] ^= bits;
					bits = (0x1<<two_bit);
					temp.Gene[two_num] ^= bits;
					//cout<<".";
				}
				totalMutaNum++;
			}
		}
		/*		
		if(((double)rand()/RAND_MAX)<prob){
			int one,two;
			int one_num,two_num,one_bit,two_bit;
			one=(int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);
			one_num=one/(sizeof(OneChmType)*8);
			one_bit=one-one_num*(sizeof(OneChmType)*8);

			two=one;
			while(++two<GeneLen){
				two_num=two/(sizeof(OneChmType)*8);
				two_bit=two-two_num*(sizeof(OneChmType)*8);
				if(  (((temp.Gene[one_num]>>one_bit)^(temp.Gene[two_num]>>two_bit))&0x01)==1  )
					break;
			}
			
			if(two<GeneLen){
				OneChmType bits = (0x1<<one_bit);
				temp.Gene[one_num] ^= bits;
				bits = (0x1<<two_bit);
				temp.Gene[two_num] ^= bits;
			}
		}
		*/
	}else{
	
		for(int i=0; i<GeneLen; i++)
		{
			int cNum = i/(sizeof(OneChmType)*8);		//所在组
			int bit = i-cNum*(sizeof(OneChmType)*8);	//组内偏移
			OneChmType bits = (0x1<<bit);
			if(((double)rand()/RAND_MAX)<prob){
				temp.Gene[cNum] ^= bits;
			}
		}
	}
	return temp;
}

//两性繁殖函数,一点交叉算子
bool Chromosome::OneCross(Chromosome& lover, Chromosome& chld1, Chromosome& chld2)
{
	if(GeneLen != lover.GeneLen) return false;
	int bits, bit;
	bits = (int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);	//产生交叉点
	int cNum = bits/(sizeof(OneChmType)*8);		//交叉点所在的数组下标
	bit = bits-cNum*(sizeof(OneChmType)*8);		//交叉点数组内叉点
	OneChmType high, low;
	high = 0xffffffffffffffff<<bit;			//交叉点数组运算
	low = ~high;
	chld1.GeneLen = GeneLen;	chld1.Gene[cNum] = 0;
	chld2.GeneLen = GeneLen;	chld2.Gene[cNum] = 0;
	chld1.Gene[cNum] = (Gene[cNum]&high)+(lover.Gene[cNum]&low);
	chld2.Gene[cNum] = (lover.Gene[cNum]&high)+(Gene[cNum]&low);

	//修正的1点交叉,交换交叉点以后的所有位
	for(int i=cNum+1; i<ChromNum; i++)				//保持交叉点左边不变
	{
		chld1.Gene[i] = Gene[i];
		chld2.Gene[i] = lover.Gene[i];
	}
	for(i=0; i<cNum; i++)				//交换交叉点右边所有位
	{
		chld1.Gene[i] = lover.Gene[i];
		chld2.Gene[i] = Gene[i];
	}
	return true;
}

//两性繁殖,两点交叉算子
bool Chromosome::TwoCross(Chromosome &lover, Chromosome &chld1, Chromosome &chld2)
{
	if(GeneLen != lover.GeneLen) return false;
	int bit1, bit2, bitt;
	bit1 = (int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);	//产生交叉点1,2
	bit2 = (int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);
	if(bit1 > bit2) {
		bitt = bit1;
		bit1 = bit2;
		bit2 = bitt;
	}
	int cNum1 = bit1/(sizeof(OneChmType)*8);	//交叉点1,2数组下标
	int cNum2 = bit2/(sizeof(OneChmType)*8);

	//修正的2点交叉,交换两个交叉点之间的所有位
	for(int i=0; i<ChromNum; i++)		//其它组运算
	{
		if(i<cNum1 || i>cNum2)			// 1,2点两边保持不变
		{
			chld1.Gene[i] = Gene[i];
			chld2.Gene[i] = lover.Gene[i];
		}
		else if(i!=cNum1 && i!=cNum2)	// 1,2点中间交换
		{
			chld1.Gene[i] = lover.Gene[i];
			chld2.Gene[i] = Gene[i];
		}
	}
	//两个交叉数组运算
	int bbit1 = bit1-cNum1*(sizeof(OneChmType)*8);	// 1,2交叉数组内叉点
	int bbit2 = bit2-cNum2*(sizeof(OneChmType)*8);
	chld1.Gene[cNum1] = Gene[cNum1];		//交叉点1运算
	chld2.Gene[cNum1] = lover.Gene[cNum1];
	OneChmType bits;
	bits = 0xfffffffffffffff<<bbit1;
	//保持交叉点左边不变,交换右边的位
	chld1.Gene[cNum1] = (chld2.Gene[cNum1]&bits) | (Gene[cNum1]&~bits);
	chld2.Gene[cNum1] = (chld1.Gene[cNum1]&bits) | (lover.Gene[cNum1]&~bits);
	if(cNum1!=cNum2)						//交叉点2运算
	{
		//考虑到两个交叉点在一个组的情况,保持一致,便于处理
		chld1.Gene[cNum2] = lover.Gene[cNum2];
		chld2.Gene[cNum2] = Gene[cNum2];
	}
	bits = 0xfffffffffffffff<<bbit2;
	//交换交叉点左边的所有位,右边的保持不变
	chld1.Gene[cNum2] = (Gene[cNum2]&bits) | (chld1.Gene[cNum2]&~bits);
	chld2.Gene[cNum2] = (lover.Gene[cNum2]&bits) | (chld2.Gene[cNum2]&~bits);
	return true;
}

//两性繁殖,均匀交叉算子
bool Chromosome::UniCross(Chromosome& lover,Chromosome& chld1, Chromosome& chld2)
{
	if(GeneLen != lover.GeneLen) return false;
	OneChmType bit;
	for(int i=0; i<GeneLen; i++)
	{
		int cNum = i/(sizeof(OneChmType)*8);
		if((i-cNum*(sizeof(OneChmType)*8))==0) bit = 0x1;
		if(((float)rand()/RAND_MAX)>.5)
		{
			chld1.Gene[cNum] |= (this->Gene[cNum] & bit);
			chld2.Gene[cNum] |= (lover.Gene[cNum] & bit);
		}
		else
		{
			chld1.Gene[cNum] |= (lover.Gene[cNum] & bit);
			chld2.Gene[cNum] |= (this->Gene[cNum] & bit);
		}
		bit <<= 1;
	}
	return true;
}

//自我交叉算子(Self crossover)
bool Chromosome::SelfCross(Chromosome& chld)
{
	int crossBits,one,two;
	int one_num,two_num,one_bit,two_bit;
	int tmp1,tmp2;

	totalCrossNum++;

	for(int i=0; i<ChromNum; i++)		
	{
		chld.Gene[i] = Gene[i];
	}
	
	crossBits=(int)((float)rand()/RAND_MAX*(GeneLen/3)+.5);
	for (i=0;i<crossBits;i++){
		do{
			one=(int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);
			two=(int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);
		}while(one==two);

		one_num=one/(sizeof(OneChmType)*8);
		one_bit=one-one_num*(sizeof(OneChmType)*8);	
		two_num=two/(sizeof(OneChmType)*8);
		two_bit=two-two_num*(sizeof(OneChmType)*8);	

		tmp1=chld.Gene[one_num]&(0x01<<one_bit);
		tmp2=chld.Gene[two_num]&(0x01<<two_bit);
		if(tmp1==0)
			chld.Gene[two_num]&=(~(0x01<<two_bit)); //set 0
		else
			chld.Gene[two_num]|=(0x01<<two_bit); //set 1
		if(tmp2==0)
			chld.Gene[one_num]&=(~(0x01<<one_bit)); //set 0
		else
			chld.Gene[one_num]|=(0x01<<one_bit); //set 1
	}
	
	
/*
	int left1,left2,right1,right2,length;
	while(1){
		length=(int)((float)rand()/RAND_MAX*(GeneLen/2)+.5);	//产生交叉段长度
		left1 = (int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);	//产生第一个交叉段头
		right2 = (int)((float)rand()/RAND_MAX*(GeneLen-1)+.5);  //产生第二个交叉段尾
		if(right2-left1 > length*2) 
			break;
	}
	right1=left1+length-1;
	left2=right2-length+1;

	//定义临时交换空间
	OneChmType *tmp1=new OneChmType[length/sizeof(OneChmType)+1];
	OneChmType *tmp2=new OneChmType[length/sizeof(OneChmType)+1];
	//第一个段拷贝到临时空间
	int begin;
	int left1_num = left1/(sizeof(OneChmType)*8);
	int right1_num = right1/(sizeof(OneChmType)*8);
	int left1_bit = left1-left1_num*(sizeof(OneChmType)*8);	
	int right1_bit = right1-right1_num*(sizeof(OneChmType)*8);
	for(int i=left1_num,j=0;i<=right1_num;i++,j++){
		tmp1[j]=Gene[i];
	}

	//第二个段拷贝到临时空间
	int left2_num = left2/(sizeof(OneChmType)*8);
	int right2_num = right2/(sizeof(OneChmType)*8);
	int left2_bit = left2-left2_num*(sizeof(OneChmType)*8);	
	int right2_bit = right2-right2_num*(sizeof(OneChmType)*8);

	for(i=0; i<ChromNum; i++)		//其它组运算
	{
		if(i<left1_num || i>right2_num || (i>right1_num)&&(i<left2_num))			
		{
			chld.Gene[i] = Gene[i];
		}
	}
		
	delete tmp1[];
	delete tmp2[];
*/	
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -