📄 moga2.cpp
字号:
#include "moga2.h"#include "aleatorio.h"Representacion::Representacion(int b,int ngenes,double *linf, double *lsup, int *pres,int iguales){ int j=0; bits=0; base=b; presicion=new(int[ngenes]); bitsXgene=new(int[ngenes]); lInf=new(double[ngenes]); lSup=new(double[ngenes]); for(int i=0;i<ngenes;i++){ presicion[i]=pres[j];//cuantos decimales de presicion se trabajara //calculo del numero de bits bitsXgene[i]=(int)ceil(log((lsup[j]-linf[j])*pow(10,pres[j])*1.000001)/log(base)); bits+=bitsXgene[j]; lInf[i]=linf[j];//lower bound lSup[i]=lsup[j];//upperbound if(iguales!=1)j++; } cout<<bits<<"bits\n"; nGenes=ngenes;}int Representacion::retBits(){ return bits;}Representacion::~Representacion(){ delete [] presicion; delete [] bitsXgene; delete [] lInf; delete [] lSup;}/* Metodo que copia un arreglo de enteros (genotipo) hacia memoria y regresa un puntero hacia ese espacio de memoria */void Representacion::copia(int *num,int *num2,int n){ int *pnum=num; for(int i=0;i<n;i++,pnum++,num2++)//recorre todo el genotipo,haciendo *pnum=*num2;//una copia hacia la memoria creada.}void Representacion::copia(double *num,double *num2,int n){ double *pnum=num; for(int i=0;i<n;i++,pnum++,num2++)//recorre todo el genotipo,haciendo *pnum=*num2;//una copia hacia la memoria creada.}/*Metodo que convierte de Gray a binario*/int *Representacion::gray_A_binario(int *g){ int *b=new int[bits]; int *pb; pb=b; int valor=*g; *pb=valor; g++; pb++; for(int k=1;k<bits;k++,g++,pb++){ if(*g==1)valor=(valor==1)?0:1; //simula el not. *pb=valor; } return b;}/* metodo que a partir de un arreglo de enteros (genotipo(simulacion de arreglo binario)) de codifica su valor (fenotipo) dentro de un rango minimo y un rango maximo */double Representacion::decodifica (int cual,int *num){ double fenotipo=0.0; int cantbits=0; int i; int *cadena,*pb; if(base==2) //si es base 2 entonces decodifica a binario cadena=gray_A_binario(num); else cadena=num; for(i=0;i<cual;i++) cantbits+=bitsXgene[i]; pb=cadena; for(i=0;i<bitsXgene[cual];i++)//recorrer todo el genotipo, para hacer la suma fenotipo+=ldexp(pb[i+cantbits],i);//de las potencias de dos reespectivas y if(base==2) delete [] cadena; double regreso=(lInf[cual]+fenotipo*(lSup[cual]-lInf[cual])/(pow(base,bitsXgene[cual])-1)); //mediante la formula que dio en clase adecuo los valores dentro de los return regreso;}/*metodo que imprime el genotipo*/void Representacion::imprime(double *num,int n){ for(int i=0;i<n;i++,num++)//recorre el genotipo, e imprime su valor. cout<<*num<<" ";}void Representacion::imprime(int *num,int n){ for(int i=0;i<n;i++,num++)//recorre el genotipo, e imprime su valor. cout<<*num<<" ";}/* metodo que genera un genotipo con la seleccion del valor de los alelos al azar con probabilidad de 0.5*/int *Representacion::genera(){ int *gtemp,*genotipo; genotipo=new(int[bits]);//asigna memoria hacia el genotipo a generar gtemp=genotipo; for(int i=0;i<bits;i++,gtemp++){//genera el genotipo, alelo a alelo,mediante *gtemp=(int)Aleatorio(0,base-1);//probabilidad. } return genotipo;//regresa el genotipo generado}/* metodo que genera un genotipo con la seleccion del valor de los alelos al azar con probabilidad de 0.5*/int *Representacion::inicializa(){ int *gtemp,*genotipo; genotipo=new(int[bits]);//asigna memoria hacia el genotipo a generar gtemp=genotipo; for(int i=0;i<bits;i++,gtemp++)//genera el genotipo, alelo a alelo,mediante *gtemp=0;//probabilidad. return genotipo;//regresa el genotipo generado}/* Metodo que cruza dos genotipos, a partir de dos posiciones dadas (cruza de dos puntos)*/void Representacion::cruza(int *padre1,int *padre2,int posicion1,int posicion2){ int cambio; for(int i=0;i<bits;i++,padre1++,padre2++){ cambio=(posicion1<=i&&i<=posicion2)?1:0; if(cambio){ int t=*padre1; *padre1=*padre2; *padre2=t; } }}/* metodo que muta a un genotipo a partir de una probabilidad dada y regresa el numero de mutaciones efecutadas*/int Representacion::muta(int *padre,float Pm){ int *ptemp, mutaciones=0,r; ptemp=padre; for(int i=0;i<bits;i++,ptemp++){//recorre el genotipo, y si el flip da int valor=flip(Pm); if(valor){//1 entonces muta mutaciones++; do{ r=(int) Aleatorio(0,base-1);} while(r==*ptemp); *ptemp=r; } } return mutaciones;//regresa el total de las mutaciones.}/* Metodo donde se efectua la cruza, y la mutacion. */void MOGAII::CruzaYMutacion(){ //se recorre la poblacion generada, de 2 en dos, y de acuerdo al Pc y a Pm //se cruzan y se mutan int pDeCruza[2],menor; for(int i=0;i<M;i+=2){ if(flip(Pc)){//para checar si va a haber cruza pDeCruza[0]=(int)Aleatorio(1,bits-2);//se busca el punto de //cruza1 y dos y se realiza la cruza do pDeCruza[1]=(int)Aleatorio(1,bits-2); while(pDeCruza[1]==pDeCruza[0]); menor=(pDeCruza[0]<pDeCruza[1])?0:1; cruza(poblacionNueva[i].genotipo,poblacionNueva[i+1].genotipo,pDeCruza[menor],pDeCruza[1-menor]); } muta(poblacionNueva[i].genotipo,Pm);//se muta de acuerdo a Pm muta(poblacionNueva[i+1].genotipo,Pm);//se muta de acuerdo a Pm evalua(poblacionNueva[i].genotipo,poblacionNueva[i].aptObj);//se calcula su aptitud evalua(poblacionNueva[i+1].genotipo,poblacionNueva[i+1].aptObj);//se calcula su aptitud }}/*Selecci'on por universal estocastico:Propuesta por Baker (1987)El objetivo es minimizar la mala distribuci'on de los individuos en la poblaci'on en funci'on de sus valores esperados.El algoritmo es O(n)*/void MOGAII::Seleccion(){ double media=0; //se recorre la poblacion, para encontrar al mas apto, y se almacena //tambien en este ciclo se hace la suma de aptitudes sumaValores=0; //Calculo de los valores esperados. for(int i=0;i<M;i++) sumaValores+=poblacion[i].apt;//se hace la suma de aptituds media=sumaValores/M;//se saca la media (aptitudes entre poblacion for(int i=0;i<M;i++){ poblacion[i].valEsp=poblacion[i].apt/media; } /* for(int i=0;i<M;i++) cout<<poblacion[arrordenado[i]].valEsp<<endl; exit(0); */}void MOGAII::NuevaPoblacion(){ double aleatorio; //generacion de la nueva poblacion a partir de la ruleta double ptr=Aleatorio2(0,1);//probabilidad. double sum=0.0; int j=0; for(int i=0;i<M;i++){ int repetido=0; for(sum+=poblacion[arrordenado[i]].valEsp;sum>ptr;ptr+=1,j++){ copia(poblacionNueva[j].genotipo,poblacion[arrordenado[i]].genotipo,bits);//se almacena el genotipo seleccio;//nado y se dispone ha generar al 2oindividuo poblacionNueva[j].rank=poblacion[arrordenado[i]].rank; // if(repetido>1)cout<<"encontre uno\n"; repetido++; } }}void MOGAII::GenerarPoblacionAleatoria(){ poblacion=new (Individuo[M]); poblacionNueva=new (Individuo[M]); for(int i=0;i<M;i++){ poblacion[i].genotipo=genera(); poblacionNueva[i].genotipo=genera(); poblacion[i].aptObj=new (double[nObjs]); poblacionNueva[i].aptObj=new (double[nObjs]); poblacion[i].aptObjEsc=new (double[nObjs]); poblacionNueva[i].aptObjEsc=new (double[nObjs]); poblacion[i].loc=0; poblacionNueva[i].loc=0; // evalua(poblacion[i].genotipo,poblacion[i].aptObj); }}void MOGAII::EvaluarPoblacion(){ for(int i=0;i<M;i++) evalua(poblacion[i].genotipo,poblacion[i].aptObj);}void MOGAII::evalua(int *genotipo,double *aptObj){ double x1,x2; double q_=4,alfa=2,PI=3.1415926; x1=decodifica(0,genotipo); x2=decodifica(1,genotipo); aptObj[0]=x1; aptObj[1]=(1+10*x2)*(1-(pow(x1/(1+10*x2),alfa))-(x1/(1+10*x2)*sin(2*PI*q_*x1)));}void MOGAII::NuevaGeneracion(){ Individuo *poblatemp; poblatemp=poblacion;//ahora la poblacion incial, va a ser la que poblacion=poblacionNueva;//va a ser generada (pero sin adicion extra de memoria) poblacionNueva=poblatemp;//y la generada, ahora se convierte en la //padre}MOGAII::MOGAII(int gmax,int m, double pc, double pm,int ngenes,int nobjs,double *linf, double *lsup, int *pres,int tampareto):Representacion(2,ngenes,linf,lsup,pres,1){ M=m; Pc=pc; nGenes=ngenes; nObjs=nobjs; Pm=pm; Gmax=gmax; srand(time(0)); malla=new MallaAdap(nobjs,tampareto,bits);}void MOGAII::ImprimeValores(){ for(int i=0;i<M;i++){ if(poblacion[i].rank==1) cout<<poblacion[i].aptObj[0]<<" "<<poblacion[i].aptObj[1]<<endl; }}/* Funcion que indica si un individuo domina a otrosi el primero domina al segundo retorna 1si el segundo domina al primero retoruna -1si son iguales retorna 0si ninguno domina retorna 11*/int MOGAII::Domina(Individuo *I1,Individuo *I2){ int anterior = 0; int mejor; double *ind1=I1->aptObj; double *ind2=I2->aptObj; /* if (ind1[0]<=ind2[0]&&ind1[1]<ind2[1] || ind1[0]<ind2[0]&&ind1[1]<=ind2[1])return 1; else if(ind1[0]>=ind2[0]&&ind1[1]>ind2[1] || ind1[0]>ind2[0]&&ind1[1]>=ind2[1])return -1; else return 0; */ // int a=restricciones(I1->genotipo); // int b=restricciones(I2->genotipo); // if(a<b)//el primero domina // return 1; // else if(b<a)//el segundo domina // return -1; for(int i=0;i<nObjs;i++,ind1++,ind2++){ if(*ind1 <*ind2) mejor = 1; else if(*ind2<*ind1)mejor = -1; else mejor = 0; if(mejor!=anterior&&anterior!=0&&mejor!=0) return(11); if(mejor!=0) anterior = mejor; } return(anterior); }void MOGAII::AsignarJerarquia(){ NMayor=0; Individuo *pp=poblacion; for(int i=0;i<M;i++) poblacion[i].rank=1; for(int i=0;i<M;i++){ for(int j=0;j<M;j++){ switch(Domina(pp+i,pp+j)){ case 11://nadie domina case 0://son iguales break;//no pasa nada case 1://el primero domina al segundo //poblacion[j].rank++; //if(NMayor<poblacion[j].rank)NMayor=poblacion[j].rank; break; case -1://el segundo domina al primero poblacion[i].rank++; if(NMayor<poblacion[i].rank)NMayor=poblacion[i].rank; break; } } } // ImprimeValores(); //exit(0);}void MOGAII::AsignarAptitudLineal(){ double *sumatoriaApt=new (double[M]); int *cantidadSumApt=new(int[M]); arrordenado=new(int[M]); for(int i=0;i<M;i++){ sumatoriaApt[i]=0; cantidadSumApt[i]=0; arrordenado[i]=0; } //ordenamiento del arreglo mediante llaves en arrordenado y calculo de la aptitud for(int i=0,k=M+1,l=0;i<M;i++){ for(int j=0;j<M;j++){ if(poblacion[j].rank==i+1){ sumatoriaApt[poblacion[j].rank-1]+=pow(k,2); cantidadSumApt[poblacion[j].rank-1]++; k--; arrordenado[l]=j; l++; } } } //promediar la aptitud de los individuos con similar jerarqu'ia for(int i=0;i<M;i++){ poblacion[i].apt=sumatoriaApt[poblacion[i].rank-1]/cantidadSumApt[poblacion[i].rank-1]; // cout<<poblacion[arrordenado[i]].apt<<endl; }}void MOGAII::calculoSigmaShare(){ double *max=new double[nObjs]; double *min=new double [nObjs]; double sumatoria=0; for(int i=0;i<nObjs;i++){ min[i]=10*pow(10,5); max[i]=-10*pow(10,5); } for(int i=0;i<M;i++){ for(int j=0;j<nObjs;j++){ min[j]=(min[j]<poblacion[i].aptObj[j])?min[j]:poblacion[i].aptObj[j]; max[j]=(max[j]>poblacion[i].aptObj[j])?max[j]:poblacion[i].aptObj[j]; } } for(int i=0;i<nObjs;i++) sumatoria+=pow(max[i]-min[i],2); q=3; sigmaShare=sumatoria/(M-1); //sigmaShare=sqrt(sumatoria)/pow(2*q,1/nObjs); //cout<<sigmaShare<<endl;}void MOGAII::EscalarApt(){ double *max=new(double[nObjs]); for(int i=0;i<nObjs;i++) max[i]=-10000; for(int i=0;i<M;i++) for(int j=0;j<nObjs;j++) max[j]=(poblacion[i].aptObj[j]>max[j])?poblacion[i].aptObj[j]:max[j]; for(int i=0;i<M;i++) for(int j=0;j<nObjs;j++) poblacion[i].aptObjEsc[j]=poblacion[i].aptObj[j]/max[j];}void MOGAII::AsignarAptitudCompartida(){ double *sumatoriaPhis=new(double[M]); for(int i=0;i<M;i++)sumatoriaPhis[i]=0; for(int i=0;i<M;i++){ for(int j=i+1;j<M;j++){ double dist=0; for(int k=0;k<nObjs;k++) dist+=pow(poblacion[i].aptObjEsc[k]-poblacion[j].aptObjEsc[k],2); dist=sqrt(dist); if(dist<sigmaShare){ sumatoriaPhis[i]+=1-(dist/sigmaShare); sumatoriaPhis[j]+=1-(dist/sigmaShare); } } poblacion[i].apt/=sumatoriaPhis[i]; poblacion[i].apt+=1/(poblacion[i].rank); }}void MOGAII::Algoritmo(){ GenerarPoblacionAleatoria(); Individuo *pp=poblacion; EvaluarPoblacion(); AsignarJerarquia(); AsignarAptitudLineal(); calculoSigmaShare(); EscalarApt(); AsignarAptitudCompartida(); for(int i=0;i<M;i++) malla->FunPARETO(pp+i); for(int i=0;i<Gmax;i++){ Seleccion(); NuevaPoblacion(); CruzaYMutacion(); NuevaGeneracion(); AsignarJerarquia(); AsignarAptitudLineal(); calculoSigmaShare(); EscalarApt(); AsignarAptitudCompartida(); for(int i=0;i<M;i++) malla->FunPARETO(pp+i); } malla->ImprimeValores(); //ImprimeValores();}int main(){ double *linf,*lsup; int *pre,p=6; int nObjs=2; int nGenes=2; double pc=0.8; double pm=1.0/40.0; int gmax=200; int m=100; int tampareto=100; linf=new(double[nObjs]); linf[0]=0; linf[1]=0; lsup=new(double[nObjs]); lsup[0]=1; lsup[1]=1; pre=new(int[nObjs]); pre[0]=6; pre[1]=6; MOGAII moga2(gmax,m,pc,pm,nGenes,nObjs,linf,lsup,pre,tampareto); moga2.Algoritmo(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -