#include<iostream.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define POPSIZE 10
#define NUMG 10
#define MAXVOL 10
#define MAXVAL 20
#define CAPACITY 30
#define MAXB (1024)
#define SIM 0.90
#define CP 1.0
#define MP 0.2
#define DIST 13
//程序中用到的HASH表结构定义
typedef struct Node{
int Fitness;
struct Node *Next;
}HASHNODE;//链表结点
typedef struct Head{
int maxFitness;
int Count;
int Diff;
HASHNODE *Next;
}HEAD;//头结点
HEAD hashTable[DIST];
//The representation of the item;
typedef struct{
int Weight;
int Fitness;
int Gene[NUMG];
}GENE;
//随即生成的基因组
GENE parentGenome[NUMG]={
{0,0,{0,0,1,0,1,1,0,1,0,1}},
{0,0,{0,0,1,1,0,0,0,1,0,1}},
{0,0,{0,0,0,1,1,0,0,0,1,1}},
{0,0,{0,1,0,0,0,1,0,1,1,0}},
{0,0,{1,0,1,0,0,1,1,0,0,1}},
{0,0,{1,1,0,0,0,1,0,0,1,1}},
{0,0,{0,1,0,0,0,1,0,1,1,0}},
{0,0,{1,0,1,1,0,1,0,0,0,0}},
{0,0,{1,1,1,0,1,1,0,1,0,0}},
{0,0,{1,1,1,1,0,0,0,0,0,0}}
};
GENE nextGenome[NUMG];
//需要装入背包的物品
int Weight[NUMG]={6,9,8,8,6, 1, 10,5,7, 1};
int Value[NUMG]={2,20,5,4,19,14,18,8,11,6};
int indexPF[POPSIZE];
int indexCF[POPSIZE];
///////////////////////////////////////////////////////
void calculateCapacity(GENE * Genome,int iD){
Genome[iD].Weight = 0;
for(int j=0; j<NUMG ;j++){
if(Genome[iD].Gene[j]==1){
Genome[iD].Weight += Weight[j];
}
}
}
void calculateFitness(GENE * Genome,int iD){
Genome[iD].Fitness = 0;
for(int j=0; j<NUMG ;j++){
if(Genome[iD].Gene[j]==1){
Genome[iD].Fitness += Value[j];
}
}
}
void checkCapacity(GENE * Genome,int iD){
while(Genome[iD].Weight>CAPACITY){
int idModify = rand()%NUMG;
if(Genome[iD].Gene[idModify]==1){
Genome[iD].Gene[idModify] = 0;
Genome[iD].Weight -= Weight[idModify];
Genome[iD].Fitness -= Value[idModify];
}
}
}
////////////////////////////////////////////////////////
void initHashTable(HEAD * hashTable){
for(int i=0; i<DIST ;i++){
hashTable[i].maxFitness = 0;
hashTable[i].Count = 0;
hashTable[i].Diff= 0;
hashTable[i].Next = NULL;
}
}
//初始化HASH表
int maxFitness(HEAD *hashTable){
int maxF = hashTable[0].maxFitness;
int index =0;
for(int i=1; i<DIST ;i++){
if(hashTable[i].maxFitness>maxF){
maxF = hashTable[i].maxFitness;
index = i;
}
}
return index;
}
//判断适应度Fitness是否已经在HASH表中
HASHNODE* isAlreadyExist(HASHNODE *pHead,int Fitness){
HASHNODE *lastPos = NULL;
while(NULL!=pHead){
if(pHead->Fitness==Fitness){
break;
}
//cout<<pHead->Fitness<<endl;
lastPos = pHead;
pHead = pHead->Next;
}
return pHead;
}
//遍历HASH表
void TraverseHashTable(HEAD * hashTable){
int index = 0;
HASHNODE *lastPos = NULL;
cout<<“I:”<<“MAX:”<<“C:”<<“D:”<<“O”<<endl;
for(int i=0; i<DIST ;i++){
if(hashTable[i].Count==0){
continue;
}
cout<<i<<“:”<<hashTable[i].maxFitness<<“:”<<hashTable[i].Count<<“:”<<hashTable[i].Diff<<“:”;
lastPos = hashTable[i].Next;
cout<<“Content:”;
while(NULL!=lastPos){
cout<<lastPos->Fitness<<“:”;
lastPos = lastPos->Next;
}
cout<<endl;
}
}
/////////////////////////////////////////////////////////////////////
bool checkFitness(){
HASHNODE *pNode = NULL;
int index = 0;
bool sameFlag = true;
initHashTable(hashTable);
for(int i=0; i<POPSIZE ;i++){
index = parentGenome[i].Fitness%DIST;
hashTable[index].Count++;
pNode = isAlreadyExist(hashTable[index].Next,parentGenome[i].Fitness);
if(NULL==pNode){
pNode = new HASHNODE;
hashTable[index].Diff++;
pNode->Next = hashTable[index].Next;
pNode->Fitness = parentGenome[i].Fitness;
if(parentGenome[i].Fitness>hashTable[index].maxFitness){
hashTable[index].maxFitness = parentGenome[i].Fitness;
}
hashTable[index].Next = pNode;
}
}
index = maxFitness(hashTable);
double CPount = hashTable[index].Count/(double)POPSIZE;
double pDiff = hashTable[index].Diff/(double)POPSIZE;
if(CPount>=0.9 && pDiff<=0.1){
sameFlag = false;
}
TraverseHashTable(hashTable);
return sameFlag;
}
/////////////////////////////////////////////////////////////////////
int Begin = 0;
int End = 1;
//计算从Begin-End位置的染色体的适应度之和
int summaryFitness(int Begin,int End){
int summaryF = 0;
if(Begin<End){
for(int i=Begin; i<End ;i++){
summaryF += parentGenome[i].Fitness;
}
}else{
for(int i=Begin; i<POPSIZE ;i++){
summaryF += parentGenome[i].Fitness;
}
for(i=0; i<End ;i++){
summaryF += parentGenome[i].Fitness;
}
}
return summaryF;
}
/////////////////////////////////////////////////////////////////////
//赌轮选择染色体以便于交叉操作
int selectIndex(){
double randProb = 0.0;
double crossProb = 0.0;
int summaryBE = 0;
int summaryF = 0;
int index;
bool flag = true;
randProb = rand()%1000/1000.0;
summaryF = summaryFitness(0,POPSIZE);
while(flag){
summaryBE = summaryFitness(Begin,End);
crossProb = (double)summaryBE/(double)summaryF;
if(crossProb>randProb){
index = End;
Begin = End;
flag = false;
}
End++;
if(End>POPSIZE){
End = 1;
}
}
return index;
}
//////////////////////////////////////////////////////////////
bool visitedFlag[POPSIZE];
//获取当前HASH表中的最大Fitness的索引
int selectedMaxFitness(GENE *Genome){
int maxPos = 0;
for(int i=0; i<POPSIZE ;i++){
if(!visitedFlag[i]){
maxPos = i;
i = POPSIZE;
}
}
for(i=0; i<POPSIZE ;i++){
if(!visitedFlag[i]&&Genome[maxPos].Fitness<Genome[i].Fitness){
maxPos = i;
}
}
return maxPos;
}
//////////////////////////////////////////////////////////////
//索引排序
void sortFitness(int *indexFitness,GENE *Genome){
memset(visitedFlag,false,NUMG*sizeof(bool));
for(int i=0; i<POPSIZE ;i++){
indexFitness[i] = selectedMaxFitness(Genome);
visitedFlag[indexFitness[i]] = true;
}
}
//精英策略:保持优秀的父染色体
void keepBestParents(){
for(int i=POPSIZE*8/10; i<POPSIZE ;i++){
parentGenome[indexPF[i]].Fitness = parentGenome[indexPF[i-POPSIZE*8/10]].Fitness;
parentGenome[indexPF[i]].Weight = parentGenome[indexPF[i-POPSIZE*8/10]].Weight;
for(int j=0; j<NUMG ;j++){
parentGenome[indexPF[i]].Gene[j] = parentGenome[indexPF[i-POPSIZE*8/10]].Gene[j];
}
}
}
////////////////////////////////////////////////////////////
void updateGeneration(){
keepBestParents();
for(int i=0; i<POPSIZE*8/10 ;i++){
parentGenome[indexPF[i]].Fitness = nextGenome[indexCF[i]].Fitness;
parentGenome[indexPF[i]].Weight = nextGenome[indexCF[i]].Weight;
for(int j=0; j<NUMG ;j++){
parentGenome[indexPF[i]].Gene[j] = nextGenome[indexCF[i]].Gene[j];
}
}
}
void crossOver(){
int partPos;
sortFitness(indexPF,parentGenome);
for(int i=0; i<POPSIZE/2 ;i++){
partPos = rand()%NUMG;
int Father = selectIndex();
int Mother = selectIndex();
for(int j=0; j<partPos ;j++){
nextGenome[i].Gene[j] = parentGenome[Father].Gene[j];
nextGenome[i+POPSIZE/2].Gene[j] = parentGenome[Mother].Gene[j];
}
for(;j<NUMG;j++){
nextGenome[i].Gene[j] = parentGenome[Father].Gene[j];
nextGenome[i+POPSIZE/2].Gene[j] = parentGenome[Mother].Gene[j];
}
calculateCapacity(nextGenome,i);
calculateFitness(nextGenome,i);
checkCapacity(nextGenome,i);
calculateCapacity(nextGenome,i+POPSIZE/2);
calculateFitness(nextGenome,i+POPSIZE/2);
checkCapacity(nextGenome,i+POPSIZE/2);
}
sortFitness(indexCF,nextGenome);
}
void mutation(){
for(int i=0; i<POPSIZE ;i++){
double prob = (rand()%1000)/1000.0;
if(prob<MP){
int partPos = rand()%NUMG;
if(nextGenome[i].Gene[partPos]==1){
nextGenome[i].Gene[partPos]=0;
nextGenome[i].Weight -= Weight[partPos];
nextGenome[i].Fitness -= Value[partPos];
}else{
if(nextGenome[i].Weight+Weight[partPos]<CAPACITY){
nextGenome[i].Gene[partPos]=1;
nextGenome[i].Weight += Weight[partPos];
nextGenome[i].Fitness += Value[partPos];
}else{
//don’t mutate!
}
}
}
}
}
void printGenome(){
for(int i=0; i<POPSIZE ;i++){
cout<<parentGenome[i].Weight<<“-“;
cout<<parentGenome[i].Fitness<<“-“;
for(int j=0; j<NUMG ;j++){
cout<<parentGenome[i].Gene[j];
}
cout<<endl;
}
}
void main(){
int nGenerations = 1000;
int nCount = 0;
bool flag = true;
int indexMaxResult = 0;
for(int i=0; i<POPSIZE ;i++){
for(int j=0; j<NUMG ;j++){
if(parentGenome[i].Gene[j]==1){
parentGenome[i].Weight += Weight[j];
parentGenome[i].Fitness += Value[j];
}
}
checkCapacity(parentGenome,i);
}
//generateChromosomes();
//generatePopulation();
printGenome();
flag = checkFitness();
cout<<“——-“<<nCount<<“——-“<<endl;
while(flag&&nCount<nGenerations){
nCount++;
crossOver();
mutation();
updateGeneration();
printGenome();
flag = checkFitness();
cout<<“——-“<<nCount<<“——-“<<endl;
}
cout<<nCount<<endl;
indexMaxResult = maxFitness(hashTable);
if(nCount<nGenerations){
cout<<“The maxValue is “<<hashTable[indexMaxResult].maxFitness<<endl;
cout<<“The information in Genome is as below:”<<endl;
printGenome();
}else{
cout<<“OH,Sorry!”;
cout<<“The maxValue may be “<<hashTable[indexMaxResult].maxFitness<<endl;
cout<<“The information in Genome is as below:”<<endl;
printGenome();
}
}