home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_1.ZIP
/
GA.ZIP
/
SOURCE.ZIP
/
GDRIVER.CPP
next >
Wrap
C/C++ Source or Header
|
1994-01-10
|
7KB
|
226 lines
//Copyright (C) Man Machine Interfaces 1994. All rights reserved.
//gdriver.cpp
//Used as an interface class to the GA.
//Stores the representation of the graph as
//a connection grid.
//required headers
#include "stdafx.h"
//Headers needed for EOS programs
//You need EOS v1.1 to compile this code
#include "eos.h"
#include "eosutil.h"
#include "geno.h"
#include "individ.h"
#include "gaenviro.h"
//headers specific to graph GA
#include "wmatrix.h"
#include "gdriver.h"
#include "grphutil.h"
#include "graphga.h"
//GA parameters used, these need not be
//hard coded in advanced implementations
const int POP_SIZE = 20 ;
const double PX = 0.7 ;
const double PM = 0.03 ;
const double RAND_SEED=0.76451 ;
//DRAWING parameters used, these need not be
//hard coded in advanced implementations
const int CELL_WIDTH = 30 ;
const int CELL_HEIGHT = 30 ;
const int CELL_SPACE = 30 ;
//Driver constructor initializes a graph with numNodes and a
//grid that the graph will be optimized to draw on (width x height)
CGAGraphDriver::CGAGraphDriver(int numNodes, int width, int height)
{
m_NumGraphNodes = numNodes;
m_GridWidth = width ;
m_GridHeight = height ;
//graph represented as boolean connection matrix
m_pGraph = new CWordMatrix(m_NumGraphNodes,m_NumGraphNodes) ;
//The Graph GA object
m_pTheGA = new CGraphDrawerGA(*this) ;
m_pBest = NULL ;
m_pWorst = NULL ;
m_Stop = FALSE ;
}
//Clean up in the destructor
CGAGraphDriver::~CGAGraphDriver()
{
delete m_pGraph ;
delete m_pTheGA ;
}
//set the conections from graph into the member m_pGraph
void CGAGraphDriver::SetGraph(CWordMatrix &graph)
{
for (int row = 0 ; row < m_NumGraphNodes; row++)
for (int col = 0 ; col < m_NumGraphNodes; col++)
m_pGraph->SetAt(row,col,graph[row][col]) ;
}
//Optimize the drawing of the graph by first initializing the
//GA's population and environment. Then execute the
//GA for numGenerations generations
void CGAGraphDriver::Optimize(int numGenerations)
{
m_pTheGA->CreatePopulation(POP_SIZE) ;
m_pTheGA->CreateEnvironment(PX,PM,RAND_SEED) ;
m_pTheGA->Evolve(numGenerations) ;
}
//Draw the optimized graph on the Windows DC
void CGAGraphDriver::DrawOptimized(CDC &dc)
{
CWordMatrix *pGrid ;
m_pBest->GetPhenoInfo(&pGrid) ;
Draw(dc,*pGrid) ;
}
//Draw the un-optimized graph on the Windows DC
void CGAGraphDriver::DrawUnOptimized(CDC &dc)
{
CWordMatrix *pGrid ;
m_pWorst->GetPhenoInfo(&pGrid) ;
Draw(dc,*pGrid) ;
}
void CGAGraphDriver::Draw(CDC &dc, CWordMatrix &Grid)
{
CPen *pPen = (CPen *) dc.SelectStockObject(BLACK_PEN) ;
for (int row = 0 ; row < m_GridHeight; row++)
for (int col = 0 ; col < m_GridWidth; col++) {
if (Grid[row][col] != EMPTY_CELL) {
int x1 = col * (CELL_WIDTH + CELL_SPACE) + CELL_SPACE ;
int x2 = x1 + CELL_WIDTH ;
int y1 = row * (CELL_HEIGHT + CELL_SPACE) + CELL_SPACE ;
int y2 = y1 + CELL_HEIGHT ;
dc.Ellipse(x1,y1,x2,y2) ;
char buffer[4] ;
sprintf(buffer,"%d",Grid[row][col]) ;
dc.TextOut(x1+CELL_WIDTH/4,y1+CELL_HEIGHT/4,buffer,strlen(buffer)) ;
}
}
//draw arcs
for (int node1 = 0 ; node1 < m_NumGraphNodes; node1++)
for (int node2 = 0 ; node2 < m_NumGraphNodes; node2++)
if (m_pGraph->GetAt(node1,node2)) {
int row1, col1 ;
Grid.Find(node1, row1, col1) ;
int row2, col2 ;
Grid.Find(node2, row2, col2) ;
int x1 = col1 * (CELL_WIDTH + CELL_SPACE) + CELL_SPACE ;
int x2 = col2 * (CELL_WIDTH + CELL_SPACE) + CELL_SPACE ;
int y1 = row1 * (CELL_HEIGHT + CELL_SPACE) + CELL_SPACE ;
int y2 = row2 * (CELL_HEIGHT + CELL_SPACE) + CELL_SPACE ;
if (x1 < x2)
x1 += CELL_WIDTH ;
else
if (x2 < x1)
x2 += CELL_WIDTH ;
else
if (x1 == x2) {
if (Abs(row1 - row2) > 1) { //route around!
y1 += CELL_WIDTH/2 ;
y2 += CELL_WIDTH/2 ;
int x3 = x1 - CELL_WIDTH/2 ;
dc.MoveTo(x1,y1) ;
dc.LineTo(x3,y1) ;
dc.LineTo(x3,y2) ;
dc.LineTo(x2,y2) ;
continue ;
}
x1 += CELL_WIDTH/2 ;
x2 += CELL_WIDTH/2 ;
}
if (y1 < y2)
y1 += CELL_HEIGHT ;
else
if (y2 < y1)
y2 += CELL_HEIGHT ;
else
if (y1 == y2) {
if (Abs(col1 - col2) > 1) { //route around!
if (x1 < x2) {
x1 -= CELL_WIDTH/2 ;
x2 += CELL_WIDTH/2 ;
}
else {
x1 += CELL_WIDTH/2 ;
x2 -= CELL_WIDTH/2 ;
}
int y3 = y1 - CELL_HEIGHT/2 ;
dc.MoveTo(x1,y1) ;
dc.LineTo(x1,y3) ;
dc.LineTo(x2,y3) ;
dc.LineTo(x2,y2) ;
continue ;
}
y1 += CELL_HEIGHT/2 ;
y2 += CELL_HEIGHT/2 ;
}
dc.MoveTo(x1,y1) ;
dc.LineTo(x2,y2) ;
}
dc.SelectObject(pPen ) ;
}
//Calculate the length of the chromosome needed to encode
//a drawing of the graph in a grid
UINT CGAGraphDriver::CalcChromosomeLength() const
{
return m_NumGraphNodes*(GetNumBitsToEncode(m_GridHeight)+GetNumBitsToEncode(m_GridWidth));
}
UINT CGAGraphDriver::CalcRowAlleleLength() const
{
return (UINT) GetNumBitsToEncode(m_GridWidth) ;
}
UINT CGAGraphDriver::CalcColAlleleLength() const
{
return (UINT) GetNumBitsToEncode(m_GridHeight) ;
}
//Return TRUE if node1 is connected to node2
BOOL CGAGraphDriver::Connected(WORD node1, WORD node2) const
{
return m_pGraph->GetAt(node1,node2) ;
}
//Returns the number of connection leaving node
int CGAGraphDriver::GetNumConnections(WORD node) const
{
int count = 0 ;
for (WORD i=0;i<m_NumGraphNodes;i++)
if (i != node && m_pGraph->GetAt(node,i))
count++ ;
return count ;
}
//Returns the total number of connections in the graph
int CGAGraphDriver::GetConnectivity()
{
int count = 0 ;
for (WORD node1=0;node1<m_NumGraphNodes;node1++)
for (WORD node2=0;node2<m_NumGraphNodes;node2++)
if (node1 != node2 && m_pGraph->GetAt(node1,node2))
count ++ ;
return count ;
}
void CGAGraphDriver::Stop()
{
m_Stop = TRUE ;
}