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

📄 cls.cpp

📁 机器学习中一个重要的方法——概念学习系统。
💻 CPP
字号:
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <dos.h>
#include "scs2.h"
int        maxrule;
int        chromnum;
float      pcross = 0.6,pmutation = 0.033,sumfitness;
float      avg,max,min;
Chromosome *chrom,*newchrom;
FILE	   *fp,*fpd;
int		   gen = 0,maxgen;
const int rulelen = 17;
const int attrnum = 4;
const int attrlen[attrnum] = {4,4,4,4};

void checkvalid(Chromosome * checkchrom,int index);

int main(int argc,char *argv[])
{
	char filename[12];
	srand(time(NULL));
	if (argc == 2)
	{strcpy(filename,argv[1]);
	 do{
		cout<<"Input number of chroms(1.."<<MAXCHROM<<"):";
		cin>>chromnum;
		}while(chromnum>MAXCHROM);
	}
	else if (argc == 3)
	{strcpy(filename,argv[1]);
	 chromnum = atoi(argv[2]);
	}
	else
	{
		cout<<"Input a string like nDmC,such as 1d1c"<<endl;
		cout<<"n & m is a integer between 1 and 4"<<endl;
		cin>>filename;
		do{
			cout<<"Input number of chroms(1.."<<MAXCHROM<<"):";
			cin>>chromnum;
		}while(chromnum>MAXCHROM);
	}
	assert(strlen(filename) == 4);
	if (!isdigit(filename[0])||!isdigit(filename[2])||
		(filename[1] != 'd' && filename[1] != 'D')||
		(filename[3] != 'c' && filename[3] != 'C'))
		{
		cout<<"Usage:prein[ndmc][chromnum]"<<endl;
		cout<<"such as:prein 1D1C 10"<<endl;
		cout<<"n&m is a integer between 1 and 4"<<endl;
		return 1;
		}
	if(!(fp = fopen(filename,"rt")))
		{
		 cout<<"file"<<filename<<"doesn't exists"<<endl;
		return 1;
		}
	strcat(filename,".DAT");
//	strcat(filename,".txt");
	if (!(fpd = fopen(filename,"wt")))
	{
		 cout<<"file"<<filename<<"append error"<<endl;
		 return 1;
	}
	cout.setf(ios::left,ios::adjustfield);
	cout<<"input maximum generation"<<endl;
	cin>>maxgen;
	assert(maxgen>0);
	initdata();
	objfunc(chrom);
	statistics(chrom);
	while(gen < maxgen)
	{
		gen++;
		report();
		generation();
		objfunc(newchrom);
		replace();
		objfunc(chrom);
		statistics(chrom);
	}
	report();
	fprintf(fpd,"\n");
	delete[]chrom;
	delete[]newchrom;
	fclose(fp);
	fclose(fpd);
	return 0;
}


/*初始化群体*/
void initdata(void)
{
	int i,j,len;
	maxrule = MAXLEN / rulelen;//maxrule number in a chromosome
	chrom = new Chromosome[chromnum];
	newchrom = new Chromosome[chromnum];
	if (!chrom || !newchrom)
	{
	cout<<"no enough memory to run this program"<<endl;
	fclose(fp);
	fclose(fpd);
	exit(1);
	}
	for(i=0;i<chromnum;i++)
	{
		chrom[i].Rulenum = rand()%maxrule + 1;//at least 1 rule
		chrom[i].Parent1 = chrom[i].Parent2 = 0;
		len = chrom[i].Rulenum * rulelen;
		for(j=0;j<len;j++)chrom[i].String[j] = (Allele)(rand()%2);
		checkvalid(chrom,i);//check valid of string,prevent all zero attribute
	}
}

/*检查染色体的有效性*/
void checkvalid(Chromosome * checkchrom,int index)
{
	Boolean flag;
	int curbit = 0,changebit;
	int i,j,k;
	for(i=0;i<checkchrom[index].Rulenum;i++)
	{
		for(j=0;j<attrnum;j++)
		{
			flag = T;
			for(k=0;k<attrlen[j];k++)
				if (checkchrom[index].String[curbit+k] == T)
				{
					flag = F;
					break;
				}
				if (flag == T)
				{
					changebit = curbit + rand()%attrlen[j];
					checkchrom[index].String[changebit] = T;
				}
				curbit +=  attrlen[j];
		}
		curbit ++;
	}
}

/*从染色体中抽取实例*/
void extractstr(char *str,int curbit,int length,int index)
{
	int i;
	for(i=0;i<length;i++)
	{
		if (chrom[index].String[curbit+i] == F)
			*str = '0';
		else
			*str = '1';
			str ++;
	}
	*str = '\0';
}

/*显示染色体及其适应度*/
void report(void)
{
	int i,j,k;
	int curbit;
	char str[20];
	cout<<endl;
	for(i=0;i<chromnum;i++)
	{
		curbit = 0;
		for(j=0;j<chrom[i].Rulenum;j++)
		{
			for(k=0;k<attrnum;k++)
			cout<<"F"<<setw(attrlen[k])<<k+1;
			cout<<"class";
		}
		cout<<"fitness"<<endl;	
		for(j=0;j<chrom[i].Rulenum;j++)
		{
			for(k=0;k<attrnum;k++)
			{
				extractstr(str,curbit,attrlen[k],i);
				curbit += attrlen[k];
				cout<<setw(attrlen[k]+1)<<str;
			}
			extractstr(str,curbit,1,i);
			curbit ++;
			cout<<""<<setw(6)<<str;
		}
		cout<<""<<chrom[i].Fitness;
		cout<<endl<<endl;
	}
	 cout<<"max = "<<max<<endl;
	 cout<<"avg = "<<avg<<endl;
	 cout<<"min = "<<min<<endl;
	 cout<<endl<<endl;
}

/*统计群体的最大、最小、平均适应度*/
void statistics(Chromosome *pop)
{
	int j,maxfindex = 0;
	min = max = sumfitness = pop[0].Fitness;
	for(j=1;j<chromnum;j++)//Loop for max,min,sumfitness
	{sumfitness += pop[j].Fitness;
		if (pop[j].Fitness>max)
		{max = pop[j].Fitness;
		 maxfindex = j;
		}
		if (pop[j].Fitness<min)min = pop[j].Fitness;
	}
	avg = sumfitness/chromnum;
	fprintf(fpd,"%f\n",chrom[maxfindex].Fitness);
}

/*生成随机数0,1*/
inline float random01(void)
{
	return rnd(0,1);
}

/*生成范围在low与high之间的一个随机数*/
float rnd(int low,int high)
{
	int i;
	float j;
	i=rand();
	j=low+(high - low)* float(i)/float(RAND_MAX);
	return j;
}

Boolean flip(float val)
{
	float j=rnd(0,1);
	if (j<=val) return T;
	else return F;
}

/*生成下一代群体*/
void generation(void)
{
	//Creat a new generation through; select, crossover,and mutation
	int j,mate1,mate2;
	int even_number =(chromnum%2)?(chromnum-1):chromnum;
	//If chrom number is a odd number,then the last don't crossover
	j = 0;
	while (j<even_number)
	{mate1=select();//Pick pair of mates
	 mate2=select();
	 crossover(mate1,mate2,j);
	 j += 2;
	}
	if (even_number != chromnum)
	{
		for(mate1=0;mate1 < chrom[j].Rulenum * rulelen;mate1++)
		newchrom[j].String[mate1]=mutation(chrom[j].String[mate1]);
		newchrom[j].Rulenum=chrom[j].Rulenum;
		newchrom[j].Parent1=newchrom[j].Parent2=j;
		checkvalid(newchrom,j);
	}
}

int select (void)
{
	float rand,partsum=0.0;
	int j=-1;
	rand=random01()*sumfitness;
	do {
		j++;
		partsum+=chrom[j].Fitness;
		}while((partsum<rand)&&(j!=chromnum-1));
	return j;//Return individual number
}

Allele mutation(Allele alleleval)
{
	//Mutate an allele w/[pmuatation, count number of mutations
	Boolean mutate;
	mutate=flip(pmutation);
	if (mutate == T)
		return (Allele)(!alleleval);
	else
		return alleleval;
}

void crossover(int parent1,int parent2,int child)
{
	//Cross 2 parent strings,place in 2 child strings
	int r1,r2,b,i;
	int len1,len2;
	Boolean flag = T;
	r1 = rand()%chrom[parent1].Rulenum;
	r2 = rand()%chrom[parent2].Rulenum;
	b = rand()%rulelen;
	len1 = r1 + chrom[parent2].Rulenum - r2;
	len2 = r2 + chrom[parent1].Rulenum - r1;
	if (len1>maxrule||len2>maxrule)
		flag=F;
	if ((flag == T)&&flip(pcross))
	{
		newchrom[child].Rulenum=len1;
		newchrom[child+1].Rulenum=len2;
		newchrom[child].Parent1=newchrom[child+1].Parent1=parent1;
		newchrom[child].Parent2=newchrom[child+1].Parent2=parent2;
		len1 = r1*rulelen + b;
		len2 = chrom[parent2].Rulenum*rulelen - r2*rulelen - b;
		for (i=0;i<len1;i++)
			newchrom[child].String[i]=mutation(chrom[parent1].String[i]);
		for(i=0;i<len2;i++)
			newchrom[child].String[len1+i]=
			mutation(chrom[parent2].String[r2*rulelen+b+i]);
			len1 = r2*rulelen + b;
			len2 = chrom[parent1].Rulenum*rulelen - r1*rulelen - b;
		 for(i=0;i<len1;i++)
			newchrom[child+1].String[i]=mutation(chrom[parent2].String[i]);
		for (i=0;i<len2;i++)
			newchrom[child+1].String[len1+i]=
		      mutation(chrom[parent1].String[r1*rulelen+b+i]);
	}
	else
	{
		newchrom[child].Rulenum=chrom[parent1].Rulenum;
		newchrom[child+1].Rulenum=chrom[parent2].Rulenum;
		newchrom[child].Parent1=newchrom[child].Parent2=parent1;
		newchrom[child+1].Parent1=newchrom[child+1].Parent2=parent2;
	for (i=0;i<chrom[parent1].Rulenum*rulelen;i++)
		newchrom[child].String[i]=mutation(chrom[parent1].String[i]);
	for(i=0;i<chrom[parent2].Rulenum*rulelen;i++)
		newchrom[child+1].String[i]=mutation(chrom[parent2].String[i]);
	}
	checkvalid(newchrom,child);
	checkvalid(newchrom,child+1);
}

/*适应度=正确分类数、实例总数(=256)*/
void objfunc(Chromosome *pop)
{
	const int len =rulelen + 1;
	char str[len];
	int fi[MAXCHROM];
	int  i=0,j,k;
	Allele flag;
	int bitoftrue;
	for(;i<chromnum;i++)  fi[i] = 0;
	while (fread(str,sizeof(char),len,fp) == len)
	{
		for (i=0;i<chromnum;i++)
		{
			for(j=0;j<pop[i].Rulenum;j++)
			{
				bitoftrue = 0;
				flag = T;
				for(k=0;k<attrnum;k++)
				{
				  while(str[bitoftrue] =='0')
					  bitoftrue++;
					  if(pop[i].String[j*rulelen + bitoftrue] == F)
					  {
						  flag=F;
						  break;
					  }
						  else bitoftrue++;
				}
				if((flag == T)&&(str[rulelen-1]-'0')==
						(int)(pop[i].String[j*rulelen+rulelen-1]))
				{
					 fi[i] ++;
					 break;
				 }/*if*/
			}/*j,Rulenum*/
		}/*i,chromnum*/
	}/*fread*/
			  for(i=0;i<chromnum;i++)
				  pop[i].Fitness=float(fi[i])/256.0;//total examples
			  rewind(fp);
}

/*若两个父代染色体通过遗传操作生成的两个子代中有一个染色体
的适应度高于父代中较差的,则用子代中适应度高的去代替父代中较差的染色体*/
void replace(void)
{
	int even_number=(chromnum%2)?(chromnum-1):chromnum;
	int i = 0;
//	Boolean flag;
	int maxofchild,minofparent;
	while(i<even_number)
	{
		maxofchild = (newchrom[i].Fitness > newchrom[i+1].Fitness)?i:i+1;
		minofparent = (chrom[newchrom[i].Parent1].Fitness < chrom[newchrom[i].Parent2].Fitness) ?newchrom[i].Parent1:newchrom[i].Parent2;
		if (newchrom[maxofchild].Fitness > chrom[minofparent].Fitness)
		{
			chrom[minofparent].Rulenum =newchrom[maxofchild].Rulenum;
			for(int j=0;j<newchrom[maxofchild].Rulenum*rulelen;j++)
			chrom[minofparent].String[j] = newchrom[maxofchild].String[j];

		}
		i += 2;
	}
	if(even_number!=chromnum)
	{
		if (newchrom[i].Fitness>chrom[newchrom[i].Parent1].Fitness)
		{
			chrom[newchrom[i].Parent1].Rulenum = newchrom[i].Rulenum;
			for(int j=0;j<newchrom[i].Rulenum*rulelen;j++)
				chrom[newchrom[i].Parent1].String[j] = newchrom[i].String[j];
		}
	}
}

⌨️ 快捷键说明

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