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

📄 ga.cpp

📁 有时间约束的车辆数优化的C程序(遗传算法)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	free(dSiteWeight);
	free(dCarCapacity);
	return OK;
}


/******************************************************************/
/*       函数名:  Randomize(low,high)                            */
/*       参  数:  low--随机数的下限                              */
/*                 high--随机数的上限                             */
/*       返回值:  生成的随机数(类型为整数)                     */
/*       功  能:  随机产生随机产生指定范围内整数                 */
/******************************************************************/

int Randomize(int low, int high)
{
	return low+rand()%(high-low+1);
	
}

/******************************************************************/
/*   函数名:  CalculateFitnessValue(stIndividual)                */
/*   参  数:  stIndividual--个体,计算后改变其适应度值           */
/*   返回值:  OK-1; NO-0                                         */
/*   功  能:  对stIndividual计算其适应度值                       */
/******************************************************************/
int CalculateFitnessValue(struct individual *stIndividual)
{
	double dSumTime=0.0,dSumWeight=0.0;
	double dBeta;
	int ret;
	
	dBeta=100.0-dAlpha;//dAlpha+dBeta=100
	ret=DecodeChromosome(stIndividual);
	if(ret==NO) return ret;
	for(int i=0; i<stIndividual->iCarNum; i++){
		dSumTime+=stIndividual->dCarFactTime[i];
		if(dCarCapacity[i]!=0.0){
			dSumWeight+=(stIndividual->dCarFactWeight[i]/dCarCapacity[i]);
		}
		else	return NO;
	}
	if(dTimeLimit!=0&&stIndividual->iCarNum!=0){
		stIndividual->dFitness = 100.0 - 
			(dAlpha*dSumTime/dTimeLimit+dBeta*dSumWeight)/stIndividual->iCarNum;
	}
	else	return NO;
	return OK;
}

/******************************************************************/
/*   函数名:  DecodeChromosome(stIndividual)                     */
/*   参  数:  stIndividual--个体                                 */
/*   返回值:  OK-1; NO-0                                         */
/*   功  能:  stIndividual解码,                                 */
/*             计算出线路数、车辆的工作量、实际容量               */
/*             iCarNum,dCarFactTime,dCarFactWeight,iLineStartPos  */
/******************************************************************/
int DecodeChromosome(struct individual *stIndividual)
{
	int pos1,pos2=0;
	double dTotalTime=0.0,dTotalWeight=0.0;

	stIndividual->iCarNum=1;
	stIndividual->iLineStartPos[0]=stIndividual->iChrom[0];
	
	for(int k=0; k<iChromLong; k++)
	{
		stIndividual->dCarFactWeight[stIndividual->iCarNum-1]=dTotalWeight;
		stIndividual->dCarFactTime[stIndividual->iCarNum-1]=dTotalTime;
		pos1=pos2;
		pos2=stIndividual->iChrom[k];
		dTotalWeight+=dSiteWeight[pos2-1];
		dTotalTime+=dRunTime[pos1][pos2]+dWorkTime[pos2-1];
		if(dTotalWeight>dCarCapacity[stIndividual->iCarNum-1] || dTotalTime>dTimeLimit){
			stIndividual->iLineStartPos[stIndividual->iCarNum]=pos2;
			stIndividual->iCarNum++;
			dTotalWeight=dSiteWeight[pos2-1];
			dTotalTime=dRunTime[0][pos2]+dWorkTime[pos2-1];
		}
	}
	stIndividual->dCarFactWeight[stIndividual->iCarNum-1]=dTotalWeight;
	stIndividual->dCarFactTime[stIndividual->iCarNum-1]=dTotalTime;
	stIndividual->iLineStartPos[stIndividual->iCarNum]='\0';
	stIndividual->dCarFactWeight[stIndividual->iCarNum]='\0';
	stIndividual->dCarFactTime[stIndividual->iCarNum]='\0';
	return OK;
}

/******************************************************************/
/*   函数名:  SimulatedAnnealing(stOldIdividual)                 */
/*   参  数:  stOldIndividual--旧个体,调用完成之后为新个体      */
/*   返回值:  OK-1; NO-0                                         */
/*   功  能:  用模拟退火算法产生局部最优个体                     */
/******************************************************************/
int SimulatedAnnealing(struct individual *stOldIndividual)
{
	int iTemp,ret;
	struct individual stTempChrom;
	double dDeltaFitness;
	double T;
	int iFirstPosition,iSecondPosition;

	if((stTempChrom.iChrom=(int*)calloc(iChromLong+1,sizeof(int)))==NULL){
		return NO;
	}
	if((stTempChrom.dCarFactTime=(double*)calloc(iChromLong+1,sizeof(double)))==NULL){
		return NO;
	}
	if((stTempChrom.dCarFactWeight=(double*)calloc(iChromLong+1,sizeof(double)))==NULL){
		return NO;
	}
	if((stTempChrom.iLineStartPos=(int*)calloc(iChromLong+1,sizeof(int)))==NULL){
		return NO;
	}
	T=dMaxTemperature;
	while(T>dMinTemperature){
		for(int j=0; j<iChromLong; j++){
			stTempChrom.iChrom[j]=stOldIndividual->iChrom[j];
		}
		stTempChrom.iChrom[j]='\0';
		for(int i=0; i<iNumCycle; i++){
			iFirstPosition=Randomize(0,iChromLong-1);
			iSecondPosition=Randomize(0,iChromLong-1);
			iTemp=stTempChrom.iChrom[iFirstPosition];
			stTempChrom.iChrom[iFirstPosition]=stTempChrom.iChrom[iSecondPosition];
			stTempChrom.iChrom[iSecondPosition]=iTemp;
			ret=CalculateFitnessValue(&stTempChrom);
			if(ret==NO)return ret;
			dDeltaFitness=stTempChrom.dFitness-stOldIndividual->dFitness;
			if(dDeltaFitness<0||exp(-dDeltaFitness/T)>Randomize(1,10000)/10000.0){
				CopyStruct(&stTempChrom,stOldIndividual);
			}
		}
		T=T*dDownRate;
	}
	free(stTempChrom.iChrom);
	free(stTempChrom.dCarFactTime);
	free(stTempChrom.dCarFactWeight);
	free(stTempChrom.iLineStartPos);
	return OK;
}

/******************************************************************/
/*   函数名:  InverseMutation(stMutationPop)                     */
/*   参  数:  stMutationPop                                      */
/*   返回值:  OK-1,NO-0                                          */
/*   功  能:  倒位交换变异产生新个体                             */
/******************************************************************/
int InverseMutation(struct individual *stMutationPop)
{
	int pos1,pos2,i;
	double p;
	int iTempChrom;

	pos1=Randomize(0,iChromLong-1);
	pos2=Randomize(0,iChromLong-1);
	p=Randomize(0,10000)/10000.0;
	if(pos2<pos1){
		i=pos2;
		pos2=pos1;
		pos1=i;
	}
	if(p<=dPMutation && pos1!=pos2){
		for(i=0; i<((pos2-pos1)/2); i++){
			iTempChrom=stMutationPop->iChrom[pos2-i];
			stMutationPop->iChrom[pos2-i]=stMutationPop->iChrom[pos1+1+i];
			stMutationPop->iChrom[pos1+1+i]=iTempChrom;
		}
	}
	return OK;
}

/******************************************************************/
/*   函数名:  TwoPointSwopMutation(stMutationPop)                */
/*   参  数:  stMutationPop                                      */
/*   返回值:  OK-1,NO-0                                          */
/*   功  能:  两点交换变异产生新个体                             */
/******************************************************************/
int TwoPointSwopMutation(struct individual *stMutationPop)
{
	int pos1,pos2;
	double p;
	int iTempChrom;

	pos1=Randomize(0,iChromLong-1);
	pos2=Randomize(0,iChromLong-1);
	p=Randomize(0,10000)/10000.0;

	if(p<=dPMutation && pos1!=pos2){
		iTempChrom=stMutationPop->iChrom[pos2];
		stMutationPop->iChrom[pos2]=stMutationPop->iChrom[pos1];
		stMutationPop->iChrom[pos1]=iTempChrom;
	}
	return OK;
}

/******************************************************************/
/*   函数名:  InsertMutation(stMutationPop)                      */
/*   参  数:  stMutationPop                                      */
/*   返回值:  OK-1,NO-0                                          */
/*   功  能:  插入变异产生新个体                                 */
/******************************************************************/
int InsertMutation(struct individual *stMutationPop)
{
	int pos1,pos2,i;
	double p;
	int iTempChrom;

	pos1=Randomize(0,iChromLong-1);
	pos2=Randomize(0,iChromLong-1);
	p=Randomize(0,10000)/10000.0;
	if(pos2<pos1){
		i=pos2;
		pos2=pos1;
		pos1=i;
	}
	if(p<=dPMutation && pos1!=pos2){
		iTempChrom=stMutationPop->iChrom[pos2];
		for(i=pos2; i>pos1+1; i--){
			stMutationPop->iChrom[i]=stMutationPop->iChrom[i-1];
		}
		stMutationPop->iChrom[i]=iTempChrom;
	}
	return OK;
}

/******************************************************************/
/*   函数名:  InsertMutation(stMutationPop,iFlag)                */
/*   参  数:  stMutationPop,iFlag                                */
/*             iFlag=1,调用InverseMutation                        */
/*             iFlag=2,调用TwoPointSwopMutation                   */
/*             iFlag=3,调用InsertMutation                         */
/*   返回值:  OK-1,NO-0                                          */
/*   功  能:  变异操作                                           */
/******************************************************************/
int MutationOperator(struct individual *stMutationPop,int iFlag)
{
	switch(iFlag){
	case 1:
		InverseMutation(stMutationPop);
		break;
	case 2:
		TwoPointSwopMutation(stMutationPop);
		break;
	case 3:
		InsertMutation(stMutationPop);
		break;
	default:
		return NO;
	}
	return OK;
}

/******************************************************************/
/*   函数名:  SelectionOperator()                                */
/*   参  数:  无                                                 */
/*   返回值:  返回个体编号                                       */
/*   功  能:  用赌盘方法选择个体                                 */
/******************************************************************/
int SelectionOperator()
{
	double dRnd=0,dSum=0;
	int i;

	dRnd=Randomize(0,10000)/10000.0;
	if((iPopSize*dMaxFitness-dSumOfFitness)!=0.0){
		for(i=0; dSum<=dRnd && i<iPopSize; i++)
			dSum+=(dMaxFitness-stOldPopulation[i].dFitness)/(iPopSize*dMaxFitness-dSumOfFitness);
	//	fprintf(outfp,"\n\t*****[%f]*****[%d]\n",iPopSize*dMaxFitness-dSumOfFitness,i-1);
	}
	else i=Randomize(1,iPopSize);

	return i-1;
}

/******************************************************************/
/*   函数名:  Statistics()                                      */
/*   参  数:  无                                                 */
/*   返回值:  Ok-1,NO-0                                          */
/*   功  能:  统计最大、最小、平均适应度,求最佳个体             */
/******************************************************************/
int Statistics()
{
	int i=0,k=0;
	dMaxFitness=-1.0;
	dMinFitness=100000.0;
	dSumOfFitness=0;
	/* 找出最佳个体的位置,汇总适应度值,找出最大、最小适应度值 */
	for(i=0; i<iPopSize; i++){
		dSumOfFitness+=stOldPopulation[i].dFitness;
		dMaxFitness=dMaxFitness<stOldPopulation[i].dFitness?stOldPopulation[i].dFitness:dMaxFitness;
		if(dMinFitness>stOldPopulation[i].dFitness){
			k=i;
			dMinFitness=stOldPopulation[i].dFitness;
		}
	}
	/* 求平均适应度值 */
	if(iPopSize!=0)
		dAvgFitness=dSumOfFitness/iPopSize;
	else dAvgFitness=0.0;
	/* 记录最佳个体 */
	for(i=0; i<iChromLong; i++)
		stBestFit.iChrom[i]=stOldPopulation[k].iChrom[i];
	stBestFit.iChrom[i]='\0';
	stBestFit.dFitness=stOldPopulation[k].dFitness;
	stBestFit.iCarNum=stOldPopulation[k].iCarNum;
	stBestFit.iGeneration=stOldPopulation[k].iGeneration;
	for(i=0; i<iChromLong && stOldPopulation[k].iLineStartPos[i]!=0x00; i++){
		stBestFit.dCarFactTime[i]=stOldPopulation[k].dCarFactTime[i];
		stBestFit.dCarFactWeight[i]=stOldPopulation[k].dCarFactWeight[i];
		stBestFit.iLineStartPos[i]=stOldPopulation[k].iLineStartPos[i];
	}
	stBestFit.dCarFactTime[i]='\0';
	stBestFit.iLineStartPos[i]='\0';
	stBestFit.dCarFactWeight[i]='\0';
	return OK;
}

/*******************************************************************/
/* 函数名:  CopyStruct(stOld,stNew)                               */
/* 参  数:  stOld:被复制个体,stNew:复制后的新个体                 */
/* 返回值:  Ok-1,NO-0                                             */
/* 功  能:  复制个体                                              */
/*******************************************************************/
int CopyStruct(struct individual *stOld, struct individual *stNew)
{
	int i=0;

	stNew->dFitness=stOld->dFitness;
	stNew->iCarNum=stOld->iCarNum;
	stNew->iGeneration=stOld->iGeneration;
	for(i=0; i<stOld->iCarNum; i++){
		stNew->dCarFactTime[i]=stOld->dCarFactTime[i];
		stNew->dCarFactWeight[i]=stOld->dCarFactWeight[i];
		stNew->iLineStartPos[i]=stOld->iLineStartPos[i];
	}
	stNew->dCarFactTime[i]='\0';
	stNew->dCarFactWeight[i]='\0';
	stNew->iLineStartPos[i]='\0';
	for(i=0; i<iChromLong; i++)
		stNew->iChrom[i]=stOld->iChrom[i];
	stNew->iChrom[i]='\0';
	stNew->iXSite1=stOld->iXSite1;
	stNew->iXSite2=stOld->iXSite2;
	stNew->iParent[0]=stOld->iParent[0];
	stNew->iParent[1]=stOld->iParent[1];
	return OK;
}

/*******************************************************************/
/* 函数名:  PartiallyMatchedCrossover(stOld1,stOld2,stNew1,stNew2)*/
/* 参  数:  stOld1,stOld2:参加交叉的旧个体                        */
/*           stNew1,stNew2:运算之后的旧个体                        */
/* 返回值:  Ok-1,NO-0                                             */
/* 功  能:  部分匹配交叉产生新个体                                */
/*******************************************************************/
int PartiallyMatchedCrossover(struct individual *stOld1,struct individual *stOld2,
							  struct individual *stNew1,struct individual *stNew2)
{
	int i=0,j=0,k;
	int pos1,pos2;
	double p;

	CopyStruct(stOld1,stNew1);
	CopyStruct(stOld2,stNew2);
	p=Randomize(0,10000)/10000.0;
	if(p<dPCross){//小于交叉概率时,才进行交叉
		pos1=Randomize(0,iChromLong-1);
		pos2=Randomize(0,iChromLong-1);
		while(pos1==pos2){
			pos2=Randomize(0,iChromLong-1);
		}
		if(pos2<pos1){
			k=pos2;
			pos2=pos1;
			pos1=k;
		}
		for(i=pos1+1; i<=pos2; i++){
			for(j=0; j<iChromLong; j++){
				if(stNew1->iChrom[j]==stOld2->iChrom[i])break;
			}
			k=stNew1->iChrom[i];
			stNew1->iChrom[i]=stNew1->iChrom[j];
			stNew1->iChrom[j]=k;
		}
		for(i=pos1+1; i<=pos2; i++){
			for(j=0; j<iChromLong; j++){
				if(stNew2->iChrom[j]==stOld1->iChrom[i])break;
			}
			k=stNew2->iChrom[i];
			stNew2->iChrom[i]=stNew2->iChrom[j];
			stNew2->iChrom[j]=k;
		}
		stNew1->iXSite1=pos1;

⌨️ 快捷键说明

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