home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_1.ZIP
/
GA.ZIP
/
SOURCE.ZIP
/
GRPHPHEN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-10
|
8KB
|
250 lines
//Copyright (C) Man Machine Interfaces 1994. All rights reserved.
//grphphen.cpp
#include "stdafx.h"
//eos headers
#include "eos.h"
#include "eosutil.h"
#include "geno.h"
//graph GA headers
#include "grphphen.h"
#include "wmatrix.h"
#include "gdriver.h"
#include "grphutil.h"
const HIGHEST_REWARD = 10 ;
const MEDIUM_REWARD = 5 ;
const SMALLEST_REWARD = 1 ;
const HIGHEST_PENALTY = 10 ;
const MEDIUM_PENALTY = 5;
const SMALLEST_PENALTY = 1;
CGraphDrawingPheno::CGraphDrawingPheno(CGAGraphDriver &driver, int width, int height)
: m_Driver(driver)
{
m_Width = width ;
m_Height = height ;
m_pGrid = new CWordMatrix(height,width,EMPTY_CELL) ; //matricies are in row-col form
m_GridIndex[0] = new int [m_Driver.GetNumNodes()];
m_GridIndex[1] = new int [m_Driver.GetNumNodes()];
}
CGraphDrawingPheno::~CGraphDrawingPheno()
{
delete m_pGrid ;
delete [] m_GridIndex[0] ;
delete [] m_GridIndex[1] ;
}
double CGraphDrawingPheno::CalcFitness()
{
WORD numNodes = (WORD) m_Driver.GetNumNodes() ;
long maxDist = (m_Width + m_Height) ;
maxDist*=maxDist;
//set base fitness so even the worst case phenotype will not bring fitness below 0
int connectivity = m_Driver.GetConnectivity() ;
double base_fitness = numNodes*(numNodes-1) * maxDist ; //* connectivity;
double fitness = base_fitness ;
for (WORD node1=0;node1<numNodes;node1++) {
int node1Connections = Max(m_Driver.GetNumConnections(node1),1);
for (WORD node2=0;node2<numNodes;node2++) {
if (node1 == node2)
continue ;
BOOL bConnected = m_Driver.Connected(node1,node2) ;
int node2Connections = Max(m_Driver.GetNumConnections(node2),1);
double distance = Distance(node1,node2) ;
distance*=distance;
if (bConnected && distance > 4) {
fitness -= distance ; //(node1Connections+node2Connections) ;
continue ;
}
if (!bConnected && distance <= 4) {
fitness -= 4/distance ; //(node1Connections+node2Connections) ;
continue ;
}
}
}
ASSERT(fitness >= 0);
return fitness ;
}
void CGraphDrawingPheno::Decode(PTGenotype pGeno)
{
WORD numNodes = (WORD) m_Driver.GetNumNodes() ;
int rowAlleleLen = m_Driver.CalcRowAlleleLength() ;
int colAlleleLen = m_Driver.CalcColAlleleLength() ;
int offset = 0 ;
for (WORD node=0;node<numNodes;node++) {
char rowAllele[16], colAllele[16] ; //we know that these are no bigger than sizeof(WORD)
for(int bit=0;bit<rowAlleleLen;bit++)
rowAllele[bit] = pGeno->GetExpressedGeneValue(offset++,0) ;
for(bit=0;bit<colAlleleLen;bit++)
colAllele[bit] = pGeno->GetExpressedGeneValue(offset++,0) ;
int codedRow = AllelesToInt(rowAllele,0, rowAlleleLen-1) ;
int codedCol = AllelesToInt(colAllele,0, colAlleleLen-1) ;
int actualRow, actualCol ;
GetNearestEmptyCell(codedRow,codedCol,actualRow,actualCol) ;
m_pGrid->SetAt(actualRow, actualCol, node) ;
m_GridIndex[0][node] = actualRow ;
m_GridIndex[1][node] = actualCol ;
}
}
PTPhenotype CGraphDrawingPheno::Copy()
{
CGraphDrawingPheno * pPheno= new CGraphDrawingPheno(m_Driver,m_Height,m_Width) ;
return pPheno ; //don't copy values because these are derived by the genotype via Decode
}
void CGraphDrawingPheno::GetPhenoInfo(void *pInfoStruct)
{
*((CWordMatrix **)pInfoStruct) = m_pGrid ;
}
void CGraphDrawingPheno::GetNearestEmptyCell(const int row, const int col, int &actualRow,int &actualCol)
{
actualRow = row % m_Height ;
actualCol = col % m_Width ;
if (m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
else { //search for "nearest" empty cell
int maxDist=Max(m_Height,m_Width) ;
int actualRow2 = actualRow ; //save actuals
int actualCol2 = actualCol ;
for (int dist=1;dist<maxDist;dist++) { //start at a distance of 1 and search outward
//first check "sides"
for(int i=-dist; i<=dist;i++) {
for(int j=-dist;j<=dist;j++) {
if (i!=j && (j==dist || j==-dist || i==dist || i==-dist)) {
actualCol = actualCol2+j ;
actualRow = actualRow2+i ;
if(actualCol >= 0 && actualCol < m_Width &&
actualRow >= 0 && actualRow < m_Height &&
m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
} //if
} // for j
} //for i
//now check 4 corners
actualCol = actualCol2+dist ;
actualRow = actualRow2+dist ;
if(actualCol < m_Width &&
actualRow < m_Height &&
m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
actualCol = actualCol2-dist ;
actualRow = actualRow2+dist ;
if(actualCol >= 0 &&
actualRow < m_Height &&
m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
actualCol = actualCol2+dist ;
actualRow = actualRow2-dist ;
if(actualCol < m_Width &&
actualRow >= 0 &&
m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
actualCol = actualCol2-dist ;
actualRow = actualRow2-dist ;
if(actualCol >= 0 &&
actualRow >= 0 &&
m_pGrid->GetAt(actualRow,actualCol) == EMPTY_CELL)
return ;
} //for dist
} //else
return ;
}
BOOL CGraphDrawingPheno::Adjacent(WORD node1, WORD node2)
{
int row1, col1 ;
if (!FindNode(node1,row1,col1))
return FALSE ;
int row2, col2 ;
//look up
row2=row1-1 ;
if (row2 >= 0 && m_pGrid->GetAt(row2,col1) == node2)
return TRUE ;
//look down
row2=row1+1 ;
if (row2 < m_Height && m_pGrid->GetAt(row2,col1) == node2)
return TRUE ;
//look left
col2=col1-1 ;
if (col2 >= 0 && m_pGrid->GetAt(row1,col2) == node2)
return TRUE ;
//look right
col2=col1+1 ;
if (col2 < m_Width && m_pGrid->GetAt(row1,col2) == node2)
return TRUE ;
return FALSE ;
}
BOOL CGraphDrawingPheno::Diagonal(WORD node1, WORD node2)
{
int row1, col1 ;
if (!FindNode(node1,row1,col1))
return FALSE ;
int row2, col2 ;
//look upper left
row2=row1-1 ;
col2=col1-1 ;
if (row2 >= 0 && col2 >= 0 && m_pGrid->GetAt(row2,col2) == node2)
return TRUE ;
//look lower left
row2=row1+1 ;
col2=col1-1 ;
if (row2 < m_Height && col2 >= 0 && m_pGrid->GetAt(row2,col1) == node2)
return TRUE ;
//look lower right
row2=row1+1 ;
col2=col1+1 ;
if (row2 < m_Height && col2 < m_Width && m_pGrid->GetAt(row1,col2) == node2)
return TRUE ;
//look upper left
row2=row1-1 ;
col2=col1+1 ;
if (row2 >= 0 && col2 < m_Width && m_pGrid->GetAt(row1,col2) == node2)
return TRUE ;
return FALSE ;
}
double CGraphDrawingPheno::Distance(WORD node1, WORD node2)
{
int row1, col1, row2, col2 ;
if (FindNode(node1,row1,col1) && FindNode(node2,row2,col2)) {
double diffRow = row1 - row2 ;
double diffCol = col1 - col2 ;
return sqrt(diffRow*diffRow + diffCol*diffCol) ;
}
else
return sqrt(m_Height*m_Height + m_Width*m_Width) ; //really an error ?!?
}
double CGraphDrawingPheno::RectDistance(WORD node1, WORD node2)
{
int row1, col1, row2, col2 ;
if (FindNode(node1,row1,col1) && FindNode(node2,row2,col2)) {
double diffRow = row1 - row2 ;
double diffCol = col1 - col2 ;
return Abs(diffRow) + Abs(diffCol) ;
}
else
return m_Height + m_Width ; //really an error ?!?
}
BOOL CGraphDrawingPheno::FindNode(const WORD node, int &row, int &col)
{
if (node >= m_Driver.GetNumNodes())
return FALSE ;
row = m_GridIndex[0][node] ;
col = m_GridIndex[1][node] ;
return TRUE ;
}