// Matt Streeter
// 2/27/00
// ESMAIN.CPP
// Implementation of class TESMainWindow; window class for main program window.
// Copyright Matt Streeter, 2000. All rights reserved
#include <owl\edit.h>
#include <owl\choosefo.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "esmain.h"
#include "eswin.rh"
#include "Network.h"
#include "Cross.hpp"
#include "Mutate.hpp"
#include "nvis.h"
#include "genwin.h"
#include "ids.h"
#include "esbutton.h"
#include "esstatic.h"
// TESGraphWindow will be redrawn every 'PLOT_INTERVAL' generations.
#define PLOT_INTERVAL 1
// Range of mutation slider.
#define MAX_MUTATION_SLIDER_POS 1000
// Set to 0 to disable saving of networks in every generation.
#define SAVE_GENERATIONS 1
static Network TestNet;
double Eval(double *weights, int count)
{
return (TestNet.NetEval(weights,count));
}
TNetworkConfigDialog::TNetworkConfigDialog(TWindow *pParent,
TNetworkConfigStruct *pTransfer): TDialog(pParent,EDIT_NETWORK_ARCHITECTURE,
::Module)
{
new TRadioButton(this,IDC_RADIOBUTTON3,0);
new TRadioButton(this,IDC_RADIOBUTTON4,0);
new TEdit(this,IDC_EDIT3,sizeof(pTransfer->pLayers));
new TEdit(this,IDC_EDIT4,sizeof(pTransfer->pNodesPerLayer));
new TEdit(this,IDC_EDIT5,sizeof(pTransfer->pTotalNodes));
new TCheckBox(this,IDC_CHECKBOX2);
SetTransferBuffer((void*)pTransfer);
}
TESConfigDialog::TESConfigDialog(TWindow *pParent,TESConfigStruct *pTransfer):
TDialog(pParent,ES_CONFIGURATION,::Module)
{
new TEdit(this,IDC_EDIT1,sizeof(pTransfer->pMu));
new TEdit(this,IDC_EDIT2,sizeof(pTransfer->pLambda));
new TRadioButton(this,IDC_RADIOBUTTON1,0);
new TRadioButton(this,IDC_RADIOBUTTON2,0);
SetTransferBuffer((void *)pTransfer);
}
DEFINE_RESPONSE_TABLE1(TESMainWindow, TESWindow)
EV_COMMAND(ID_ES_BUTTON,HandleESButtonMsg),
EV_COMMAND(CM_MAIN_ESOPTIONS,HandleESButtonMsg),
EV_COMMAND(ID_PROBLEM_BUTTON,HandleProblemButtonMsg),
EV_COMMAND(CM_MAIN_LOADPROBLEM,HandleProblemButtonMsg),
EV_COMMAND(ID_RUN_BUTTON,HandleRunButtonMsg),
EV_COMMAND(CM_MAIN_RUN,HandleRunButtonMsg),
EV_COMMAND(ID_PAUSE_BUTTON,HandlePauseButtonMsg),
EV_COMMAND(CM_MAIN_PAUSE,HandlePauseButtonMsg),
EV_COMMAND(ID_PLOT_BUTTON,HandlePlotButtonMsg),
EV_COMMAND(CM_MAIN_FITNESSPLOT,HandlePlotButtonMsg),
EV_COMMAND(ID_RESET_BUTTON,HandleResetButtonMsg),
EV_COMMAND(CM_MAIN_RESET,HandleResetButtonMsg),
EV_COMMAND(ID_NETWORK_BUTTON,HandleNetworkButtonMsg),
EV_COMMAND(CM_MAIN_NETWORKOPTIONS,HandleNetworkButtonMsg),
EV_COMMAND(ID_BEST_BUTTON,HandleBestButtonMsg),
EV_COMMAND(CM_MAIN_CURRENTBESTNETWORK,HandleBestButtonMsg),
EV_COMMAND(ID_GENERATION_BUTTON,HandleGenerationButtonMsg),
EV_COMMAND(CM_MAIN_GENERATIONS,HandleGenerationButtonMsg),
EV_CHILD_NOTIFY_ALL_CODES(ID_MUTATION_SLIDER,HandleMutationSlider),
END_RESPONSE_TABLE;
TESMainWindow::TESMainWindow(char *pTitle): TESWindow(0,pTitle)
{
Attr.X=100;
Attr.Y=100;
Attr.W=775;
Attr.H=600;
mGenerationState=NO_STATE;
mpPlotWindow = 0;
mbUseBackpropagation=0;
mpScoreList=0;
mpGenerationList=0;
mbPlus=1;
LoadConfigFile();
CreateChildren();
TestNet.InitNetwork(mES);
mES.param.InitParameter(mPInfo.GetNParams());
mES.param.InitPInfo(mPInfo);
mES.param.SetEval(Eval);
mpLBSigma=new double[mES.nsigma];
mpUBSigma=new double[mES.nsigma];
Reset();
AssignMenu(MAIN_MENU);
}
#define NEW_LAYOUT (USE_PRETTY_BUTTONS && USE_ES_STATICS)
#define ES_BUTTON_X 25
#define ES_BUTTON_Y 25
#define PROBLEM_BUTTON_X ES_BUTTON_X //275
#define PROBLEM_BUTTON_Y iProblemY // 50
#define NETWORK_BUTTON_X ES_BUTTON_X // 50
#define NETWORK_BUTTON_Y iNetworkY // 100
#define RUN_BUTTON_X iRunX
#define RUN_BUTTON_Y ES_BUTTON_Y
#define PAUSE_BUTTON_X iPauseX
#define PAUSE_BUTTON_Y ES_BUTTON_Y
#define RESET_BUTTON_X iRunX
#define RESET_BUTTON_Y NETWORK_BUTTON_Y
#define PLOT_BUTTON_X iPauseX
#define PLOT_BUTTON_Y NETWORK_BUTTON_Y
#define GENERATION_BUTTON_X iGenerationX
#define GENERATION_BUTTON_Y ES_BUTTON_Y
#define BEST_BUTTON_X iGenerationX
#define BEST_BUTTON_Y NETWORK_BUTTON_Y
#define RUN_BUTTON_WIDTH 60
#define GENERATION_HPADDING 50
#define GENERATION_NUM_STATIC_WIDTH 50
#define ES_STATIC_WIDTH 75
#define NETWORK_STATIC_WIDTH 150
#define BEST_SCORE_STATIC_WIDTH 125
#define PROBLEM_STATIC_WIDTH 300
#define MUTATION_STATIC_X ES_BUTTON_X
#define MUTATION_STATIC_Y 500
#define MUTATION_SLIDER_X ES_BUTTON_X+60
#define MUTATION_SLIDER_Y 500
// tbd: move
void TESMainWindow::CreateChildren()
{
#if(!NEW_LAYOUT)
// create buttons
mpESButton = new TESButton(this,ID_ES_BUTTON,"ES:",50,50,30,25);
mpProblemButton = new TESButton(this,ID_PROBLEM_BUTTON,"Problem:",
275,50,100,25);
mpNetworkButton = new TESButton(this,ID_NETWORK_BUTTON,"Network:",
50,100,100,25);
mpRunButton = new TESButton(this,ID_RUN_BUTTON,"Run",400,100,50,25);
mpPauseButton = new TESButton(this,ID_PAUSE_BUTTON,"Pause",475,100,50,25);
mpPlotButton = new TESButton(this,ID_PLOT_BUTTON,"Plot",550,100,50,25);
mpResetButton = new TESButton(this,ID_RESET_BUTTON,"Reset",625,100,50,25);
mpBestButton = new TESButton(this,ID_BEST_BUTTON,"Best:",475,150,50,25);
mpGenerationButton = new TESButton(this,ID_GENERATION_BUTTON,"Generation:",
50,150,100,25);
// create statics
new TESStatic(this,ID_MUTATION_STATIC,"Mutation:",50,500,75,25);
mpGenerationNumStatic=new TESStatic(this,ID_GENERATION_NUM_STATIC,"0",175,150,
50,25);
char temp[200];
GetESStaticStr(temp);
mpESStatic=new TESStatic(this,ID_ES_STATIC,temp,100,50,75,25);
GetNetworkStaticStr(temp);
mpNetworkStatic = new TESStatic(this,ID_NETWORK_STATIC,temp,175,100,200,25);
mpBestScoreStatic=new TESStatic(this,ID_BEST_SCORE_STATIC,
"NA",550,150,125,25);
GetProblemStaticStr(temp);
mpProblemStatic=new TESStatic(this,ID_PROBLEM_STATIC,temp,400,50,275,25);
mpMutationSlider = new THSlider(this,ID_MUTATION_SLIDER,150,500,300,25);
#else
// create buttons
mpESButton = new TESButton(this,ID_ES_BUTTON,"ES:",ES_BUTTON_X,ES_BUTTON_Y);
int iNetworkY=ES_BUTTON_Y+mpESButton->GetHeight()+1;
mpNetworkButton = new TESButton(this,ID_NETWORK_BUTTON,"Network:",
NETWORK_BUTTON_X,NETWORK_BUTTON_Y);
int iProblemY=NETWORK_BUTTON_Y+mpNetworkButton->GetHeight()+1;
mpProblemButton = new TESButton(this,ID_PROBLEM_BUTTON,"Problem:",
PROBLEM_BUTTON_X,PROBLEM_BUTTON_Y);
int iRunX=PROBLEM_BUTTON_X+mpProblemButton->GetWidth()+NETWORK_STATIC_WIDTH;
mpRunButton = new TESButton(this,ID_RUN_BUTTON,"Run",
RUN_BUTTON_X,RUN_BUTTON_Y,RUN_BUTTON_WIDTH,mpESButton->GetHeight());
int iPauseX=iRunX+RUN_BUTTON_WIDTH;
mpPauseButton = new TESButton(this,ID_PAUSE_BUTTON,"Pause",
PAUSE_BUTTON_X,PAUSE_BUTTON_Y,RUN_BUTTON_WIDTH,mpESButton->GetHeight());
mpResetButton = new TESButton(this,ID_RESET_BUTTON,"Reset",
RESET_BUTTON_X,RESET_BUTTON_Y,
RUN_BUTTON_WIDTH,mpNetworkButton->GetHeight());
mpPlotButton = new TESButton(this,ID_PLOT_BUTTON,"Plot",
PLOT_BUTTON_X,PLOT_BUTTON_Y,
RUN_BUTTON_WIDTH,mpNetworkButton->GetHeight());
int iGenerationX=iPauseX+RUN_BUTTON_WIDTH+GENERATION_HPADDING;
mpGenerationButton = new TESButton(this,ID_GENERATION_BUTTON,"Generation:",
GENERATION_BUTTON_X,GENERATION_BUTTON_Y);
mpBestButton = new TESButton(this,ID_BEST_BUTTON,"Best:",
BEST_BUTTON_X,BEST_BUTTON_Y);
// create statics
mpGenerationNumStatic=new TESStatic(this,ID_GENERATION_NUM_STATIC,"0",
GENERATION_BUTTON_X+mpGenerationButton->GetWidth(),GENERATION_BUTTON_Y,
GENERATION_NUM_STATIC_WIDTH,mpGenerationButton->GetHeight());
char temp[200];
GetESStaticStr(temp);
mpESStatic=new TESStatic(this,ID_ES_STATIC,temp,
ES_BUTTON_X+mpESButton->GetWidth(),ES_BUTTON_Y,
ES_STATIC_WIDTH,mpESButton->GetHeight());
GetNetworkStaticStr(temp);
mpNetworkStatic = new TESStatic(this,ID_NETWORK_STATIC,temp,
NETWORK_BUTTON_X+mpNetworkButton->GetWidth(),NETWORK_BUTTON_Y,
NETWORK_STATIC_WIDTH,mpNetworkButton->GetHeight());
mpBestScoreStatic=new TESStatic(this,ID_BEST_SCORE_STATIC,
"NA",BEST_BUTTON_X+mpBestButton->GetWidth(),BEST_BUTTON_Y,
BEST_SCORE_STATIC_WIDTH,mpBestButton->GetHeight());
GetProblemStaticStr(temp);
mpProblemStatic=new TESStatic(this,ID_PROBLEM_STATIC,temp,
PROBLEM_BUTTON_X+mpProblemButton->GetWidth(),PROBLEM_BUTTON_Y,
PROBLEM_STATIC_WIDTH,mpProblemButton->GetHeight());
// int iMutationX=PROBLEM_BUTTON_X+mpProblemButton->GetWidth()
// +PROBLEM_STATIC_WIDTH;
new TESStatic(this,ID_MUTATION_STATIC,"Mutation:",MUTATION_STATIC_X,
MUTATION_STATIC_Y,75,mpProblemButton->GetHeight());
mpMutationSlider = new THSlider(this,ID_MUTATION_SLIDER,
MUTATION_SLIDER_X,MUTATION_SLIDER_Y,300,mpProblemButton->GetHeight());
#endif
}
void TESMainWindow::SetupWindow()
{
TWindow::SetupWindow();
mpMutationSlider->SetRange(0,MAX_MUTATION_SLIDER_POS);
mpMutationSlider->SetRuler(0,FALSE);
mpMutationSlider->SetPosition(0);
}
bool TESMainWindow::IdleAction(long lIdleCount)
{
ChildrenIdleAction(lIdleCount);
if(mbRunning)
{
if(!mGenerationState)
{
InitGenerationCycle();
}
if(GenerationCycle()!=1)
return(true);
mGenerationState=NO_STATE;
UpdateBestScoreStatic();
UpdateGenerationNumStatic();
AddGenerationStats();
#if(PLOT_INTERVAL!=1) // avoid "conditional always true" warning
if(!(mES.generation%PLOT_INTERVAL))
#endif
{
RedrawPlotWindow();
UpdateMutationSlider();
}
}
return(true);
}
void TESMainWindow::HandleESButtonMsg()
{
TESConfigStruct Config;
// copy workspace parameters to transfer struct
itoa(mES.mu,Config.pMu,10);
itoa(mES.lambda,Config.pLambda,10);
Config.bPlus=mbPlus;
Config.bComma=!mbPlus;
TESConfigDialog Dialog(this,&Config);
if(Dialog.Execute()==IDOK)
{
// copy window parameters to workspace
// tbd: validate
mES.mu=atoi(Config.pMu);
mES.lambda=atoi(Config.pLambda);
mbPlus=Config.bPlus;
UpdateESStatic();
Reset();
}
}
void TESMainWindow::HandleProblemButtonMsg()
{
TOpenSaveDialog::TData FilenameData(OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,
"Training Sets (*.ts)|*.ts|All Files (*.*)|*.*|",0,"","*");
if(TFileOpenDialog(this, FilenameData, 0, "Open Training File").Execute()
== IDOK)
{
if(TestNet.LoadTrainingSet(FilenameData.FileName)<0)
{
MessageBox("File load failed!","Error!");
}
SetChromosomeLength(TestNet.NumWeights());
Reset();
UpdateProblemStatic();
}
}
void TESMainWindow::HandleRunButtonMsg()
{
if (!mbPlus && mES.mu > mES.lambda)
return;
StartRunning();
}
void TESMainWindow::HandlePauseButtonMsg()
{
PauseRunning();
}
void TESMainWindow::HandlePlotButtonMsg()
{
if(!mpPlotWindow)
(new TESGraphWindow(this,"ES Graph",&mpScoreList,&mpPlotWindow))
->Create();
}
void TESMainWindow::HandleResetButtonMsg()
{
Reset();
}
void TESMainWindow::HandleNetworkButtonMsg()
{
TNetworkConfigStruct Config;
int n;
// copy workspace parameters to transfer struct
Config.bFeedforward=1;
Config.bHopfield=0;
itoa(TestNet.GetHiddenLayers(),Config.pLayers,10);
int iHiddenNodesPerLayer=-1;
byte bAllHiddenLayersEqual=1;
for(n=1;n<TestNet.GetLayers()-1;n++)
{
if(iHiddenNodesPerLayer==-1)
{
iHiddenNodesPerLayer=TestNet.GetLayerSize(n);
}
else
{
if(iHiddenNodesPerLayer!=TestNet.GetLayerSize(n))
{
bAllHiddenLayersEqual=0;
break;
}
}
}
if(bAllHiddenLayersEqual)
{
itoa(iHiddenNodesPerLayer,Config.pNodesPerLayer,10);
}
else
{
Config.pNodesPerLayer[0]='\0';
for(n=1;n<TestNet.GetLayers()-1;n++)
{
if(n>1)
strcat(Config.pNodesPerLayer,", ");
itoa(TestNet.GetLayerSize(n),
&(Config.pNodesPerLayer[strlen(Config.pNodesPerLayer)]),10);
}
}
itoa(TestNet.GetTotalHiddenNodes(),Config.pTotalNodes,10);
Config.bUseBackpropagation=mbUseBackpropagation;
TNetworkConfigDialog Dialog(this,&Config);
if(Dialog.Execute()==IDOK)
{
// assign parameters to network
// tbd: validate
TestNet.SetNumLayers(atoi(Config.pLayers)+2);
strcat(Config.pNodesPerLayer,",");
char *pToken=strtok(Config.pNodesPerLayer,",");
int iLayer=1;
while(pToken && iLayer<TestNet.GetLayers()-1)
{
char *pPos=&(pToken[strlen(pToken)-1]);
while(pPos>pToken)
{
char c=toupper(*pPos);
if(c=='S'||c=='T'||c=='L')
{
switch(c)
{
case 'S':
TestNet.SetActivation(iLayer,ACTIVATION_SIGMOID);
break;
case 'T':
TestNet.SetActivation(iLayer,ACTIVATION_TANH);
break;
case 'L':
TestNet.SetActivation(iLayer,ACTIVATION_LINEAR);
break;
};
*pPos=0;
}
pPos--;
}
iHiddenNodesPerLayer=atoi(pToken);
TestNet.SetLayerSize(iLayer++,iHiddenNodesPerLayer);
pToken=strtok(0,",");
}
for(;iLayer<TestNet.GetLayers()-1;iLayer++)
{
TestNet.SetLayerSize(iLayer,iHiddenNodesPerLayer);
}
TestNet.AllocWeights();
SetChromosomeLength(TestNet.NumWeights());
mbUseBackpropagation=Config.bUseBackpropagation;
UpdateNetworkStatic();
Reset();
}
}
void TESMainWindow::HandleBestButtonMsg()
{
TNVisWindow *pNVisWindow=new TNVisWindow(this,&TestNet,
&(mParent.GetMember(0)),&(mES.param));
if(pNVisWindow)
pNVisWindow->Create();
}
void TESMainWindow::HandleGenerationButtonMsg()
{
TGenerationWindow *pWin;
pWin = new TGenerationWindow(this,"Generations",mpGenerationList,&TestNet,
mES.param.GetUpper(0),&(mES.param));
pWin->Create();
}
void TESMainWindow::HandleMutationSlider(UINT /*code*/)
{
int n,m;
//long double ldSpillover=0;
// double dAvgSigma=GetAverageSigma();
double dNewAvgSigma=((double)mpMutationSlider->GetPosition()
/(double)MAX_MUTATION_SLIDER_POS)*mpUBSigma[0];
for(n=0;n<mParent.size;n++)
{
for(m=mES.nvars;m<mES.nvars+mES.nsigma;m++)
{
mParent.GetMember(n).SetGene(m,dNewAvgSigma);
/*
double dNewSigma=mParent.GetMember(n).GetGene(m)*dNewAvgSigma
/dAvgSigma;
if(dNewSigma<mpLBSigma[0])
{
ldSpillover+=mpLBSigma[0]-dNewSigma;
dNewSigma=mpLBSigma[0];
}
else if(dNewSigma>mpUBSigma[0])
{
ldSpillover+=dNewSigma-mpUBSigma[0];
dNewSigma=mpUBSigma[0];
}
mParent.GetMember(n).SetGene(m,dNewSigma);
*/
}
}
/*
if(ldSpillover>0)
{
for(n=0;n<mParent.size;n++)
{
for(m=mES.nvars;m<mES.nvars+mES.nsigma;m++)
{
}
}
}
*/
}
void TESMainWindow::StartRunning()
{
mbRunning=1;
}
void TESMainWindow::PauseRunning()
{
mbRunning=0;
}
void TESMainWindow::StopRunning()
{
mbRunning=0;
}
void TESMainWindow::SetChromosomeLength(int iLen)
{
mES.SetNumVars(iLen);
mPInfo.SetNumParameters(iLen);
TestNet.InitNetwork(mES);
mES.param.InitParameter(mPInfo.GetNParams());
mES.param.InitPInfo(mPInfo);
mES.param.SetEval(Eval);
// re-allocate sigmas
delete(mpLBSigma);
delete(mpUBSigma);
mpLBSigma=new double[mES.nsigma];
mpUBSigma=new double[mES.nsigma];
}
void TESMainWindow::Reset()
{
mES.generation=0;
mbRunning=0;
mGenerationState=NO_STATE;
InitES();
InitGenerationStats();
RedrawPlotWindow();
UpdateGenerationNumStatic();
UpdateBestScoreStatic();
mpMutationSlider->SetPosition(0);
DeleteGenerationList();
SaveCurrentGeneration();
}
void TESMainWindow::RedrawPlotWindow()
{
if(mpPlotWindow)
mpPlotWindow->RedrawWindow(0,0,RDW_INVALIDATE);
}
void TESMainWindow::InitGenerationStats()
{
GenerationScore *pCurScore;
pCurScore=mpScoreList;
while(pCurScore)
{
GenerationScore *pTemp=pCurScore;
pCurScore=pCurScore->pNext;
delete(pTemp);
}
mpScoreList=0;
}
void TESMainWindow::AddGenerationStats()
{
GenerationScore *pNewScore=new GenerationScore,*pCurrent;
pNewScore->iGeneration=(int)mES.generation;
pNewScore->dDiversity=mParent.Diversity();
pNewScore->dMin=sqrt(mParent.stats.Min());
pNewScore->dMax=sqrt(mParent.stats.Max());
pNewScore->dAverage=sqrt(mParent.stats.Average());
pNewScore->dMedian=sqrt(mParent.stats.Median());
pNewScore->pNext=0;
if(!mpScoreList)
{
mpScoreList=pNewScore;
}
else
{
pCurrent=mpScoreList;
while(pCurrent->pNext)
{
pCurrent=pCurrent->pNext;
}
pCurrent->pNext=pNewScore;
}
}
int TESMainWindow::InitES()
{
int i;
mParent.InitPopulation(mES.mu, mES.clen);
mChild.InitPopulation(mES.lambda, mES.clen);
for (i=0; i<mES.nsigma; i++)
{
// mpLBSigma[i] = (mPInfo.GetUpper(i))*mES.lbsigma;
// mpUBSigma[i] = (mPInfo.GetUpper(i))*mES.ubsigma;
mpLBSigma[i] = mES.lbsigma;
mpUBSigma[i] = mES.ubsigma;
}
for (i=0; i<mES.mu; i++)
{
(mParent.GetMember(i)).Randomize(mES.rn,mES.nvars,
mES.nvars+mES.nsigma,mpLBSigma,mpUBSigma);
if (mES.usealpha)
(mParent.GetMember(i)).Randomize(mES.rn, mES.nvars
+mES.nsigma,mES.clen,-M_PI,M_PI);
}
// Randomize the X portion of the population
mParent.Randomize(mES.rn, mES.param);
mParent.Sort();
// index the parent population
for(i=0;i<mES.mu;i++)
{
mParent.GetMember(i).miIndex=i;
mParent.GetMember(i).miGeneration=0;
}
return(0);
}
int TESMainWindow::InitGenerationCycle()
{
mGenerationState=START;
miChildrenGenerated=0;
return(0);
}
int TESMainWindow::GenerationCycle()
{
int i;
switch(mGenerationState)
{
case START:
// each member of the parent population will be "its own parent" if it
// survives into the next generation
for(i=0;i<mES.mu;i++)
{
mParent.GetMember(i).miWeightParent1=mParent.GetMember(i).miIndex;
mParent.GetMember(i).miWeightParent2=-1;
mParent.GetMember(i).miSigmaParent1=mParent.GetMember(i).miIndex;
mParent.GetMember(i).miSigmaParent2=-1;
}
mGenerationState++;
break;
case GENERATE_CHILD:
if(!mbPlus)
{
ESCrossover(mES,mParent);
}
else
{
if (mES.mu > 1)
ESCrossover(mES,mParent);
else
mParent.CopyMember(0,mES.child);
}
ESMutate (mES, mpLBSigma, mpUBSigma);
mChild.AddMember(miChildrenGenerated, mES.child, mES.param);
miChildrenGenerated++;
if(miChildrenGenerated>=mES.lambda)
{
mGenerationState++;
}
break;
case MERGE:
if(!mbPlus)
{
mChild.Sort();
for (i=0; i<mES.mu; i++)
mParent.AddMember(i, mChild.GetMember(i));
}
else
{
// Now merge the children into parent population
for (i=0; i<mES.lambda; i++)
mParent.AddMember(mChild.GetMember(i));
}
mGenerationState++;
break;
case INDEX:
// index the new generation
for(i=0;i<mES.mu;i++)
{
mParent.GetMember(i).miIndex=i;
mParent.GetMember(i).miGeneration=(int)(mES.generation+1);
}
mGenerationState++;
break;
case SAVE:
mES.generation++;
SaveCurrentGeneration();
mGenerationState++;
break;
case DONE:
return(1);
default:
return(-1);
};
return(0);
}
int TESMainWindow::Generation()
{
int iResult;
InitGenerationCycle();
while(!(iResult=GenerationCycle()));
return(iResult<0?iResult:0);
#if(0)
// each member of the parent population will be "its own parent" if it
// survives into the next generation
for(i=0;i<mES.mu;i++)
{
mParent.GetMember(i).miWeightParent1=mParent.GetMember(i).miIndex;
mParent.GetMember(i).miWeightParent2=-1;
mParent.GetMember(i).miSigmaParent1=mParent.GetMember(i).miIndex;
mParent.GetMember(i).miSigmaParent2=-1;
}
// Generate lambda offspring
for (i=0; i<mES.lambda; i++)
{
if(!mbPlus)
{
ESCrossover(mES,mParent);
}
else
{
if (mES.mu > 1)
ESCrossover(mES,mParent);
else
mParent.CopyMember(0,mES.child);
}
ESMutate (mES, mpLBSigma, mpUBSigma);
mChild.AddMember(i, mES.child, mES.param);
}
if(!mbPlus)
{
mChild.Sort();
for (i=0; i<mES.mu; i++)
mParent.AddMember(i, mChild.GetMember(i));
}
else
{
// Now merge the children into parent population
for (i=0; i<mES.lambda; i++)
mParent.AddMember(mChild.GetMember(i));
}
// index the new generation
for(i=0;i<mES.mu;i++)
{
mParent.GetMember(i).miIndex=i;
mParent.GetMember(i).miGeneration=mES.generation+1;
}
mES.generation++;
SaveCurrentGeneration();
return(0);
#endif
}
int TESMainWindow::LoadConfigFile()
{
ifstream ifile("default.cfg");
ifile >> mParams;
ifile >> mES;
ifile >> mPInfo;
ifile >> TestNet;
ifile.close();
return(0);
}
void TESMainWindow::UpdateMutationSlider()
{
double dAvgSigma=GetAverageSigma();
// for now assume all parameters have the same range, so that all mpUBsigmas
// are the same. Also assume |mpUBSigma|>=|mpLBSigma|, and that
// mpUBSigma>0.
float fNormMutation=dAvgSigma/mpUBSigma[0];
if(fNormMutation<0.0f)
fNormMutation=0.0f;
if(fNormMutation>1.0f)
fNormMutation=1.0f;
mpMutationSlider->SetPosition(fNormMutation*(float)MAX_MUTATION_SLIDER_POS);
}
void TESMainWindow::UpdateESStatic()
{
char temp[200];
GetESStaticStr(temp);
mpESStatic->SetText(temp);
}
void TESMainWindow::UpdateGenerationNumStatic()
{
char temp[200];
itoa((int)mES.generation,temp,10);
mpGenerationNumStatic->SetText(temp);
}
void TESMainWindow::UpdateBestScoreStatic()
{
char temp[200];
if(!mES.generation)
{
mpBestScoreStatic->SetText("NA");
}
else
{
#if(!ATTRIBUTE_EVAL)
sprintf(temp,"%lf",sqrt(mParent.GetWorth(0)));
#else
double dFitness=mParent.GetWorth(0);
dFitness=100.0f-100.0f*dFitness;
sprintf(temp,"%lf",dFitness);
strcat(temp,"%");
#endif
mpBestScoreStatic->SetText(temp);
}
}
void TESMainWindow::UpdateProblemStatic()
{
char temp[200];
GetProblemStaticStr(temp);
mpProblemStatic->SetText(temp);
}
double TESMainWindow::GetAverageSigma()
{
long double ldSigmaSum=0;
// calculate sigma sum
for(int n=0;n<mParent.size;n++)
{
for(int m=mES.nvars;m<mES.nvars+mES.nsigma;m++)
{
double dSigma=mParent.GetMember(n).GetGene(m);
ldSigmaSum+=fabs(dSigma);
}
}
return((double)(ldSigmaSum/(long double)mParent.size
/(long double)mES.nsigma));
}
void TESMainWindow::UpdateNetworkStatic()
{
char temp[200];
GetNetworkStaticStr(temp);
mpNetworkStatic->SetText(temp);
}
void TESMainWindow::GetESStaticStr(char *pDest)
{
strcpy(pDest,"(");
itoa(mES.mu,&(pDest[strlen(pDest)]),10);
if(mbPlus)
strcat(pDest,"+");
else
strcat(pDest,",");
itoa(mES.lambda,&(pDest[strlen(pDest)]),10);
strcat(pDest,")");
}
void TESMainWindow::GetProblemStaticStr(char *pDest)
{
strcpy(pDest,TestNet.GetProblemName());
strcat(pDest," (");
itoa(TestNet.GetNumInputs(),&(pDest[strlen(pDest)]),10);
strcat(pDest,"i,");
itoa(TestNet.GetNumOutputs(),&(pDest[strlen(pDest)]),10);
strcat(pDest,"o,");
itoa(TestNet.GetNumSamples(),&(pDest[strlen(pDest)]),10);
strcat(pDest,"s)");
}
void TESMainWindow::GetNetworkStaticStr(char *pDest)
{
strcpy(pDest,"Feedforward");
strcat(pDest," ");
itoa(TestNet.GetHiddenLayers(),&(pDest[strlen(pDest)]),10);
strcat(pDest,"x");
itoa(TestNet.GetLayerSize(1),&(pDest[strlen(pDest)]),10);
}
void TESMainWindow::SaveCurrentGeneration()
{
int n;
#if(SAVE_GENERATIONS)
TGeneration *pNext=new TGeneration;
pNext->pSurvivors=new Chromosome[mParent.size];
int iChromLen=mParent.GetMember(0).GetLength();
for(n=0;n<mParent.size;n++)
{
pNext->pSurvivors[n].InitChromosome(iChromLen);
pNext->pSurvivors[n]=mParent.GetMember(n);
}
pNext->iSurvivors=mParent.size;
pNext->pDead=0;
pNext->iDead=0;
pNext->pNext=0;
// add this generation to the list
if(!mpGenerationList)
{
mpGenerationList=pNext;
}
else
{
TGeneration *pLastGeneration=mpGenerationList;
while(pLastGeneration->pNext)
pLastGeneration=pLastGeneration->pNext;
pLastGeneration->pNext=pNext;
}
#endif
}
void TESMainWindow::DeleteGenerationList()
{
TGeneration *pCurNode=mpGenerationList;
while(pCurNode)
{
TGeneration *pTemp=pCurNode;
pCurNode=pCurNode->pNext;
delete(pTemp);
}
mpGenerationList=0;
}
void TESWinApp::InitMainWindow()
{
MainWindow = new TESMainWindow("NVIS - Neural Network Visualization Tool");
}