📄 ga2dbinstrgenome.c
字号:
// $Header: /usr/people/mbwall/src/galib/ga/RCS/GA2DBinStrGenome.C,v 1.6 1999/03/27 19:18:16 mbwall Exp $
/* ----------------------------------------------------------------------------
binstr2.C
mbwall 19apr95
Copyright (c) 1995 Massachusetts Institute of Technology
all rights reserved
DESCRIPTION:
Source file for the 2D binary string genome. See the 1D genome for comments.
---------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <ga/gaerror.h>
#include <ga/garandom.h>
#include <ga/GA2DBinStrGenome.h>
#include <ga/GAMask.h>
/* ----------------------------------------------------------------------------
Genome class definition
---------------------------------------------------------------------------- */
GA2DBinaryStringGenome::
GA2DBinaryStringGenome(unsigned int width, unsigned int height,
GAGenome::Evaluator f, void * u) :
GABinaryString(width*height),
GAGenome(DEFAULT_2DBINSTR_INITIALIZER,
DEFAULT_2DBINSTR_MUTATOR,
DEFAULT_2DBINSTR_COMPARATOR) {
evaluator(f);
userData(u);
crossover(DEFAULT_2DBINSTR_CROSSOVER);
nx=minX=maxX=0; ny=minY=maxY=0;
resize(width, height);
}
GA2DBinaryStringGenome::
GA2DBinaryStringGenome(const GA2DBinaryStringGenome & orig) :
GABinaryString(orig.GABinaryString::size()),
GAGenome() {
nx=minX=maxX=0; ny=minY=maxY=0;
GA2DBinaryStringGenome::copy(orig);
}
GA2DBinaryStringGenome::~GA2DBinaryStringGenome() {
}
GAGenome *
GA2DBinaryStringGenome::clone(GAGenome::CloneMethod flag) const {
GA2DBinaryStringGenome *cpy = new GA2DBinaryStringGenome(nx,ny);
if(flag == CONTENTS){
cpy->copy(*this);
}
else{
cpy->GAGenome::copy(*this);
cpy->minX = minX; cpy->minY = minY;
cpy->maxX = maxX; cpy->maxY = maxY;
}
return cpy;
}
void
GA2DBinaryStringGenome::copy(const GAGenome & orig)
{
if(&orig == this) return;
const GA2DBinaryStringGenome* c =
DYN_CAST(const GA2DBinaryStringGenome*, &orig);
if(c) {
GAGenome::copy(*c);
GABinaryString::copy(*c);
nx = c->nx; ny = c->ny;
minX = c->minX; minY = c->minY;
maxX = c->maxX; maxY = c->maxY;
}
}
int
GA2DBinaryStringGenome::resize(int w, int h)
{
if((unsigned int)w == nx && (unsigned int)h == ny) return sz;
if(w == GAGenome::ANY_SIZE)
w = GARandomInt(minX, maxX);
else if(w < 0)
w = nx; // do nothing
else if(minX == maxX)
minX=maxX = w;
else{
if(w < STA_CAST(int, minX)) w=minX;
if(w > STA_CAST(int, maxX)) w=maxX;
}
if(h == GAGenome::ANY_SIZE)
h = GARandomInt(minY, maxY);
else if(h < 0)
h = ny; // do nothing
else if(minY == maxY)
minY=maxY = h;
else{
if(h < STA_CAST(int, minY)) h=minY;
if(h > STA_CAST(int, maxY)) h=maxY;
}
// Move the bits into the right position. If we're smaller, then shift to
// the smaller size before we do the resize (the resize method maintains bit
// integrety). If we're larger, do the move after the resize. If we're the
// same size the we don't do anything. When we're adding more bits, the new
// bits get set randomly to 0 or 1.
if(w < STA_CAST(int,nx)){
int y=GAMin(STA_CAST(int,ny),h);
for(int j=0; j<y; j++)
GABinaryString::move(j*w,j*nx,w);
}
GABinaryString::resize(w*h);
if(w > STA_CAST(int,nx)){ // adjust the existing chunks of bits
int y=GAMin(STA_CAST(int,ny),h);
for(int j=y-1; j>=0; j--){
GABinaryString::move(j*w,j*nx,nx);
for(int i=nx; i<w; i++)
bit(j*w+i, GARandomBit());
}
}
if(h > STA_CAST(int,ny)){ // change in height is always new bits
for(int i=w*ny; i<w*h; i++)
bit(i, GARandomBit());
}
nx = w; ny = h;
_evaluated = gaFalse;
return sz;
}
#ifndef NO_STREAMS
int
GA2DBinaryStringGenome::read(istream & is)
{
static char c;
unsigned int i=0, j=0;
while(!is.fail() && !is.eof() && j < ny) {
is >> c;
if(isdigit(c)){
gene(i, j, ((c == '0') ? 0 : 1));
if(++i >= nx){ // ready for next row
i=0;
j++;
}
}
}
_evaluated = gaFalse;
if(is.eof() &&
((j < ny) || // didn't get some lines
(i < nx && i != 0))){ // stopped early on a row
GAErr(GA_LOC, className(), "read", gaErrUnexpectedEOF);
is.clear(ios::badbit | is.rdstate());
return 1;
}
return 0;
}
// Dump the digits to the stream with a newline between each row. No newline
// at the end of the whole thing.
int
GA2DBinaryStringGenome::write(ostream & os) const
{
for(unsigned int j=0; j<ny; j++){
for(unsigned int i=0; i<nx; i++)
os << gene(i,j);
os << "\n";
}
return 0;
}
#endif
int
GA2DBinaryStringGenome::resizeBehaviour(GAGenome::Dimension which) const {
int val = 0;
if(which == WIDTH) {
if(maxX == minX) val = FIXED_SIZE;
else val = maxX;
}
else if(which == HEIGHT) {
if(maxY == minY) val = FIXED_SIZE;
else val = maxY;
}
return val;
}
int
GA2DBinaryStringGenome::
resizeBehaviour(Dimension which, unsigned int lower, unsigned int upper)
{
if(upper < lower){
GAErr(GA_LOC, className(), "resizeBehaviour", gaErrBadResizeBehaviour);
return resizeBehaviour(which);
}
switch(which){
case WIDTH:
minX = lower; maxX = upper;
if(nx > upper) resize(upper,ny);
if(nx < lower) resize(lower,ny);
break;
case HEIGHT:
minY = lower; maxY = upper;
if(ny > upper) resize(nx,upper);
if(ny < lower) resize(nx,lower);
break;
default:
break;
}
return resizeBehaviour(which);
}
void
GA2DBinaryStringGenome::copy(const GA2DBinaryStringGenome & orig,
unsigned int r, unsigned int s,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
if(w == 0 || x >= orig.nx || r >= nx ||
h == 0 || y >= orig.ny || s >= ny) return;
if(x + w > orig.nx) w = orig.nx - x;
if(y + h > orig.ny) h = orig.ny - y;
if(r + w > nx) w = nx - r;
if(s + h > ny) h = ny - s;
for(unsigned int j=0; j<h; j++)
GABinaryString::copy(orig, (s+j)*nx+r, (y+j)*orig.nx+x, w);
_evaluated = gaFalse;
}
void
GA2DBinaryStringGenome::set(unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
if(x + w > nx) w = nx - x;
if(y + h > ny) h = ny - y;
for(unsigned int j=0; j<h; j++)
GABinaryString::set((y+j)*nx+x, w);
_evaluated = gaFalse;
}
void
GA2DBinaryStringGenome::unset(unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
if(x + w > nx) w = nx - x;
if(y + h > ny) h = ny - y;
for(unsigned int j=0; j<h; j++)
GABinaryString::unset((y+j)*nx+x, w);
_evaluated = gaFalse;
}
void
GA2DBinaryStringGenome::randomize(unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
if(x + w > nx) w = nx - x;
if(y + h > ny) h = ny - y;
for(unsigned int j=0; j<h; j++)
GABinaryString::randomize((y+j)*nx+x, w);
_evaluated = gaFalse;
}
void
GA2DBinaryStringGenome::move(unsigned int x, unsigned int y,
unsigned int srcx, unsigned int srcy,
unsigned int w, unsigned int h)
{
if(srcx + w > nx) w = nx - srcx;
if(x + w > nx) w = nx - x;
if(srcy + h > ny) h = ny - srcy;
if(y + h > ny) h = ny - y;
if(srcy<y){
for(int j=h-1; j>=0; j--)
GABinaryString::move((y+j)*nx+x, (srcy+j)*nx+srcx, w);
}
else{
for(unsigned int j=0; j<h; j++)
GABinaryString::move((y+j)*nx+x, (srcy+j)*nx+srcx, w);
}
_evaluated = gaFalse;
}
int
GA2DBinaryStringGenome::equal(const GA2DBinaryStringGenome& orig,
unsigned int x, unsigned int y,
unsigned int srcx, unsigned int srcy,
unsigned int w, unsigned int h) const
{
unsigned int eq = 0;
for(unsigned int j=0; j<h; j++)
eq += GABinaryString::equal(orig, (y+j)*nx+x, (srcy+j)*nx+srcx, w);
return eq==h ? 1 : 0;
}
int
GA2DBinaryStringGenome::equal(const GAGenome & c) const
{
if(this == &c) return 1;
GA2DBinaryStringGenome & b = (GA2DBinaryStringGenome &)c;
if(nx != b.nx || ny != b.ny) return 0;
int val=0;
for(unsigned int j=0; j<ny && val==0; j++)
val = GABinaryString::equal(b,j*nx,j*nx,nx) ? 0 : 1;
return(val ? 0 : 1);
}
/* ----------------------------------------------------------------------------
Operators
---------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------
2D Binary String Genome
The order for looping through indices is height-then-width (ie height loops
before a single width increment)
---------------------------------------------------------------------------- */
void
GA2DBinaryStringGenome::UniformInitializer(GAGenome & c)
{
GA2DBinaryStringGenome &child=DYN_CAST(GA2DBinaryStringGenome &, c);
child.resize(GAGenome::ANY_SIZE, GAGenome::ANY_SIZE);
for(int i=child.width()-1; i>=0; i--)
for(int j=child.height()-1; j>=0; j--)
child.gene(i, j, GARandomBit());
}
void
GA2DBinaryStringGenome::UnsetInitializer(GAGenome & c)
{
GA2DBinaryStringGenome &child=DYN_CAST(GA2DBinaryStringGenome &, c);
child.resize(GAGenome::ANY_SIZE, GAGenome::ANY_SIZE);
child.unset(0, 0, child.width(), child.height());
}
void
GA2DBinaryStringGenome::SetInitializer(GAGenome & c)
{
GA2DBinaryStringGenome &child=DYN_CAST(GA2DBinaryStringGenome &, c);
child.resize(GAGenome::ANY_SIZE, GAGenome::ANY_SIZE);
child.set(0, 0, child.width(), child.height());
}
int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -