📄 ga3darraygenome.c
字号:
delete [] aset;
}
template <class T> GAGenome *
GA3DArrayAlleleGenome<T>::clone(GAGenome::CloneMethod) const {
return new GA3DArrayAlleleGenome<T>(*this);
}
template <class T> void
GA3DArrayAlleleGenome<T>::copy(const GAGenome& orig){
if(&orig == this) return;
const GA3DArrayAlleleGenome<T>* c =
DYN_CAST(const GA3DArrayAlleleGenome<T>*, &orig);
if(c) {
GA3DArrayGenome<T>::copy(*c);
if(naset != c->naset){
delete [] aset;
naset = c->naset;
aset = new GAAlleleSet<T>[c->naset];
}
for(int i=0; i<naset; i++)
aset[i].link(c->aset[i]);
}
}
template <class T> int
GA3DArrayAlleleGenome<T>::resize(int w, int h, int d){
unsigned int oldx = nx;
unsigned int oldy = ny;
unsigned int oldz = nz;
GA3DArrayGenome<T>::resize(w,h,d);
// set new elements to proper randomly selected values
if(nx > oldx && ny > oldy){
int z=GAMin(oldz,nz);
for(int k=z-1; k>=0; k--){
int j;
for(j=oldy-1; j>=0; j--)
for(unsigned int i=oldx; i<nx; i++)
a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele();
for(j=oldy; j<STA_CAST(int,ny); j++)
for(unsigned int i=0; i<nx; i++)
a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele();
}
}
else if(nx > oldx){
int z=GAMin(oldz,nz);
for(int k=z-1; k>=0; k--)
for(int j=ny-1; j>=0; j--)
for(unsigned int i=oldx; i<nx; i++)
a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele();
}
else if(ny > oldy){
int z=GAMin(oldz,nz);
for(int k=z-1; k>=0; k--)
for(unsigned int j=oldy; j<ny; j++)
for(unsigned int i=0; i<nx; i++)
a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele();
}
if(nz > oldz){ // change in depth is always new elements
for(unsigned int i=nx*ny*oldz; i<nx*ny*nz; i++)
a[i] = aset[i % naset].allele();
}
return sz;
}
#ifndef NO_STREAMS
template <class T> int
GA3DArrayAlleleGenome<T>::read(istream& is){
return GA3DArrayGenome<T>::read(is);
}
template <class T> int
GA3DArrayAlleleGenome<T>::write(ostream& os) const {
return GA3DArrayGenome<T>::write(os);
}
#endif
template <class T> int
GA3DArrayAlleleGenome<T>::equal(const GAGenome & c) const {
return GA3DArrayGenome<T>::equal(c);
}
/* ----------------------------------------------------------------------------
Operator definitions
---------------------------------------------------------------------------- */
// this does not handle genomes with multiple allele sets!
template <class ARRAY_TYPE> void
GA3DArrayAlleleGenome<ARRAY_TYPE>::UniformInitializer(GAGenome & c)
{
GA3DArrayAlleleGenome<ARRAY_TYPE> &child=
DYN_CAST(GA3DArrayAlleleGenome<ARRAY_TYPE> &, c);
child.resize(GAGenome::ANY_SIZE,GAGenome::ANY_SIZE,GAGenome::ANY_SIZE);
for(int i=child.width()-1; i>=0; i--)
for(int j=child.height()-1; j>=0; j--)
for(int k=child.depth()-1; k>=0; k--)
child.gene(i, j, k, child.alleleset().allele());
}
template <class ARRAY_TYPE> int
GA3DArrayAlleleGenome<ARRAY_TYPE>::FlipMutator(GAGenome & c, float pmut)
{
GA3DArrayAlleleGenome<ARRAY_TYPE> &child=
DYN_CAST(GA3DArrayAlleleGenome<ARRAY_TYPE> &, c);
register int n, m, d, i, j, k;
if(pmut <= 0.0) return(0);
float nMut = pmut * STA_CAST(float,child.size());
if(nMut < 1.0){ // we have to do a flip test on each bit
nMut = 0;
for(i=child.width()-1; i>=0; i--){
for(j=child.height()-1; j>=0; j--){
for(k=child.depth()-1; k>=0; k--){
if(GAFlipCoin(pmut)){
child.gene(i, j, k, child.alleleset().allele());
nMut++;
}
}
}
}
}
else{ // only flip the number of bits we need to flip
for(n=0; n<nMut; n++){
m = GARandomInt(0, child.size()-1);
d = child.height() * child.depth();
i = m / d;
j = (m % d) / child.depth();
k = (m % d) % child.depth();
child.gene(i, j, k, child.alleleset().allele());
}
}
return(STA_CAST(int,nMut));
}
template <class ARRAY_TYPE> int
GA3DArrayGenome<ARRAY_TYPE>::SwapMutator(GAGenome & c, float pmut)
{
GA3DArrayGenome<ARRAY_TYPE> &child=DYN_CAST(GA3DArrayGenome<ARRAY_TYPE>&, c);
register int n, i;
if(pmut <= 0.0) return(0);
float nMut = pmut * STA_CAST(float,child.size());
int size = child.size()-1;
if(nMut < 1.0){ // we have to do a flip test on each bit
nMut = 0;
for(i=size; i>=0; i--){
if(GAFlipCoin(pmut)){
child.GAArray<ARRAY_TYPE>::swap(i, GARandomInt(0, size));
nMut++;
}
}
}
else{ // only flip the number of bits we need to flip
for(n=0; n<nMut; n++)
child.GAArray<ARRAY_TYPE>::swap(GARandomInt(0, size),
GARandomInt(0, size));
}
return(STA_CAST(int,nMut));
}
template <class ARRAY_TYPE> float
GA3DArrayGenome<ARRAY_TYPE>::
ElementComparator(const GAGenome& a, const GAGenome& b)
{
const GA3DArrayGenome<ARRAY_TYPE>& sis=
DYN_CAST(const GA3DArrayGenome<ARRAY_TYPE>&, a);
const GA3DArrayGenome<ARRAY_TYPE>& bro=
DYN_CAST(const GA3DArrayGenome<ARRAY_TYPE>&, b);
if(sis.size() != bro.size()) return -1;
if(sis.size() == 0) return 0;
float count = 0.0;
for(int i=sis.width()-1; i>=0; i--)
for(int j=sis.height()-1; j>=0; j--)
for(int k=sis.depth()-1; k>=0; k--)
count += ((sis.gene(i,j,k) == bro.gene(i,j,k)) ? 0 : 1);
return count/sis.size();
}
// Make sure our bitmask is big enough, generate a mask, then use it to
// extract the information from each parent to stuff the two children.
// We don't deallocate any space for the masks under the assumption that we'll
// have to use them again in the future.
// For now we'll implement this only for fixed length genomes. If you use
// this crossover method on genomes of different sizes it might break!
template <class T> int
GA3DArrayGenome<T>::
UniformCrossover(const GAGenome& p1, const GAGenome& p2,
GAGenome* c1, GAGenome* c2){
const GA3DArrayGenome<T> &mom=DYN_CAST(const GA3DArrayGenome<T> &, p1);
const GA3DArrayGenome<T> &dad=DYN_CAST(const GA3DArrayGenome<T> &, p2);
int nc=0;
int i,j,k;
if(c1 && c2){
GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1);
GA3DArrayGenome<T> &bro=DYN_CAST(GA3DArrayGenome<T> &, *c2);
if(sis.width() == bro.width() && sis.height() == bro.height() &&
sis.depth() == bro.depth() &&
mom.width() == dad.width() && mom.height() == dad.height() &&
mom.depth() == dad.depth() &&
sis.width() == mom.width() && sis.height() == mom.height() &&
sis.depth() == mom.depth()){
for(i=sis.width()-1; i>=0; i--){
for(j=sis.height()-1; j>=0; j--){
for(k=sis.depth()-1; k>=0; k--){
if(GARandomBit()){
sis.gene(i,j,k, mom.gene(i,j,k));
bro.gene(i,j,k, dad.gene(i,j,k));
}
else{
sis.gene(i,j,k, dad.gene(i,j,k));
bro.gene(i,j,k, mom.gene(i,j,k));
}
}
}
}
}
else{
GAMask mask;
int startx, starty, startz;
int maxx = (sis.width() > bro.width()) ? sis.width() : bro.width();
int minx = (mom.width() < dad.width()) ? mom.width() : dad.width();
int maxy = (sis.height() > bro.height()) ? sis.height() : bro.height();
int miny = (mom.height() < dad.height()) ? mom.height() : dad.height();
int maxz = (sis.depth() > bro.depth()) ? sis.depth() : bro.depth();
int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
mask.size(maxx*maxy*maxz);
for(i=0; i<maxx; i++)
for(j=0; j<maxy; j++)
for(k=0; k<maxz; k++)
mask[i*maxy*maxz+j*maxz+k] = GARandomBit();
startx = (sis.width() < minx) ? sis.width() : minx;
starty = (sis.height() < miny) ? sis.height() : miny;
startz = (sis.depth() < minz) ? sis.depth() : minz;
for(i=startx-1; i>=0; i--)
for(j=starty-1; j>=0; j--)
for(k=startz-1; k>=0; k--)
sis.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ?
mom.gene(i,j,k) : dad.gene(i,j,k)));
startx = (bro.width() < minx) ? bro.width() : minx;
starty = (bro.height() < miny) ? bro.height() : miny;
startz = (bro.depth() < minz) ? bro.depth() : minz;
for(i=startx-1; i>=0; i--)
for(j=starty-1; j>=0; j--)
for(k=startz-1; k>=0; k--)
bro.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ?
dad.gene(i,j,k) : mom.gene(i,j,k)));
}
nc = 2;
}
else if(c1){
GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1);
if(mom.width() == dad.width() && mom.height() == dad.height() &&
mom.depth() == dad.depth() &&
sis.width() == mom.width() && sis.height() == mom.height() &&
sis.depth() == mom.depth()){
for(i=sis.width()-1; i>=0; i--)
for(j=sis.height()-1; j>=0; j--)
for(k=sis.depth()-1; k>=0; k--)
sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
}
else{
int minx = (mom.width() < dad.width()) ? mom.width() : dad.width();
int miny = (mom.height() < dad.height()) ? mom.height() : dad.height();
int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
minx = (sis.width() < minx) ? sis.width() : minx;
miny = (sis.height() < miny) ? sis.height() : miny;
minz = (sis.depth() < minz) ? sis.depth() : minz;
for(i=minx-1; i>=0; i--)
for(j=miny-1; j>=0; j--)
for(k=minz-1; k>=0; k--)
sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
}
nc = 1;
}
return nc;
}
// For even crossover we take the even bits from the mother (for the daughter)
// and the odd bits from the father. Just the opposite for the son.
// This is designed only for genomes that are the same length. If the child
// is not the same length as the parent, or if the children are not the same
// size, we don't do the crossover.
// In the interest of speed we do not do any checks for size. Do not use
// this crossover method when the parents and children may be different sizes.
// It might break!
template <class T> int
GA3DArrayGenome<T>::
EvenOddCrossover(const GAGenome& p1, const GAGenome& p2,
GAGenome* c1, GAGenome* c2){
const GA3DArrayGenome<T> &mom=DYN_CAST(const GA3DArrayGenome<T> &, p1);
const GA3DArrayGenome<T> &dad=DYN_CAST(const GA3DArrayGenome<T> &, p2);
int nc=0;
int i,j,k;
if(c1 && c2){
GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1);
GA3DArrayGenome<T> &bro=DYN_CAST(GA3DArrayGenome<T> &, *c2);
if(sis.width() == bro.width() && sis.height() == bro.height() &&
sis.depth() == bro.depth() &&
mom.width() == dad.width() && mom.height() == dad.height() &&
mom.depth() == dad.depth() &&
sis.width() == mom.width() && sis.height() == mom.height() &&
sis.depth() == mom.depth()){
int count=0;
for(i=sis.width()-1; i>=0; i--){
for(j=sis.height()-1; j>=0; j--){
for(k=sis.depth()-1; k>=0; k--){
sis.gene(i,j,k,((count%2 == 0) ? mom.gene(i,j,k):dad.gene(i,j,k)));
bro.gene(i,j,k,((count%2 == 0) ? dad.gene(i,j,k):mom.gene(i,j,k)));
count++;
}
}
}
}
else{
int startx, starty, startz;
int maxx = (sis.width() > bro.width()) ? sis.width() : bro.width();
int minx = (mom.width() < dad.width()) ? mom.width() : dad.width();
int maxy = (sis.height() > bro.height()) ? sis.height() : bro.height();
int miny = (mom.height() < dad.height()) ? mom.height() : dad.height();
int maxz = (sis.depth() > bro.depth()) ? sis.depth() : bro.depth();
int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
startx = (sis.width() < minx) ? sis.width() : minx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -