#include <stdio.h>
#include <iostream>
#include <SharkDefs.h>
#include <EALib/PVMinterface.h>
#include <Array/Array.h>
#include <EALib/Population.h>
double sphere(const std::vector< double >& x);
void pvmMasterSendReceive(Population& pop ,
char* PVM_groupname,
const int PVM_groupsize,
const int msgTagSend ,
const int msgTagReceive
);
void pvmSlaveReceiveSend(char* PVM_groupname,
const int PVM_groupsize,
const int PVM_MasterID ,
const int msgTagExit ,
const int msgTagSend ,
const int msgTagReceive,
const Interval RangeOfValues,
const unsigned NumOfBits ,
const bool UseGrayCode
);
int main(int argn, char *argv[])
{
std::cout << "# PVM process attemps to start ... "
<< std::endl;
char* PVM_groupname = "PVM-Test";
const int PVM_groupsize = 4 ;
const int PVM_sendExitTag = 3 ;
const int PVM_sendFitnessTag = 2 ;
const int PVM_sendEvalTag = 1 ;
const int PVM_MasterID = 0 ;
int inum, tid;
const unsigned PopSize = 50 ;
const unsigned Dimension = 20 ;
const unsigned NumOfBits = 10;
const unsigned Iterations = 2000;
const unsigned DspInterval = 10 ;
const unsigned NElitists = 1;
const unsigned Omega = 5;
const unsigned CrossPoints = 2;
const double CrossProb = 0.6;
const double FlipProb = 1. / (Dimension * NumOfBits);
const bool UseGrayCode = true;
const Interval RangeOfValues(-3, + 5);
unsigned i, t;
int myseed = (argn > 1 ? atoi(argv[ 1 ]) : 1234);
tid = pvm_mytid();
if (tid < 0) {
throw SHARKEXCEPTION("There is something going wrong ... \nmaybe you forgot to spawn processes from the pvm-console.\nPlease try the following. \nStart the pvm-console, i.e., call the command '... /$(PVM-binpath)/pvm'.\nAfter the pvm-console has started, for example, add 3 hosts from your local network\nto your parallel virtual machine (PVM), i.e., call 'add host1 host2 host3'.\nStart this program from the pvm console, i.e, call\n'spawn -> -4 $(SHARKHOME)/EALib/examples/pvmSphereGa<extension for your operating system> [optional random-seed]'.");
}
else
std::cout << "# ... process with TID " << tid << " started"
<< " successfully. Please hold on for results."
<< std::endl;
inum = pvm_joingroup(PVM_groupname);
pvm_barrier(PVM_groupname, PVM_groupsize);
if (inum == PVM_MasterID) {
Rng::seed(myseed);
static Population parents(PopSize, ChromosomeT< bool >(Dimension * NumOfBits));
static Population offspring(PopSize, ChromosomeT< bool >(Dimension * NumOfBits));
std::vector< double > window(Omega);
parents .setMinimize();
offspring.setMinimize();
for (i = 0; i < parents.size(); ++i)
dynamic_cast< ChromosomeT< bool >& >(parents[ i ][ 0 ]).initialize();
if (NElitists > 0)
pvmMasterSendReceive(parents, PVM_groupname, PVM_groupsize, PVM_sendEvalTag, PVM_sendFitnessTag);
for (t = 0; t < Iterations; ++t) {
offspring = parents;
for (i = 0; i < offspring.size() - 1; i += 2)
if (Rng::coinToss(CrossProb))
offspring[ i ][ 0 ].crossover(offspring[ i+1 ][ 0 ],
CrossPoints);
for (i = 0; i < offspring.size(); ++i)
dynamic_cast< ChromosomeT< bool >& >(offspring[ i ][ 0 ]).flip(FlipProb);
pvmMasterSendReceive(offspring,
PVM_groupname,
PVM_groupsize,
PVM_sendEvalTag,
PVM_sendFitnessTag);
offspring.linearDynamicScaling(window, t);
parents.selectProportional(offspring, NElitists);
if (t % DspInterval == 0)
std::cout << t << "\tbest value = "
<< parents.best().fitnessValue() << "\n";
}
for (int i = 1; i < PVM_groupsize; i++) {
pvm_initsend(PvmDataDefault);
pvm_send(pvm_gettid(PVM_groupname, i), PVM_sendExitTag);
}
}
else {
pvmSlaveReceiveSend(PVM_groupname,
PVM_groupsize,
PVM_MasterID,
PVM_sendExitTag,
PVM_sendFitnessTag,
PVM_sendEvalTag,
RangeOfValues,
NumOfBits,
UseGrayCode
);
}
pvm_barrier(PVM_groupname, PVM_groupsize);
std::cout << "# PVM process with TID " << tid << " will halt now... " << std::endl
<< std::endl;
pvm_exit();
}
double sphere(const std::vector< double >& x)
{
unsigned i;
double sum;
for (sum = 0., i = 0; i < x.size(); i++)
sum += Shark::sqr(x[ i ]);
return sum;
}
void pvmMasterSendReceive(Population& pop ,
char* PVM_groupname,
const int PVM_groupsize,
const int msgTagSend ,
const int msgTagReceive
)
{
unsigned i;
for (i = 0; i < pop.size(); ++i) {
pvm_initsend(PvmDataDefault);
pop[i].pvm_pkind();
pvm_send(pvm_gettid(PVM_groupname, i % (PVM_groupsize - 1) + 1), msgTagSend);
}
int bufid = 0; int counter = pop.size();
while (counter > 0) {
do {
bufid = pvm_probe(-1, msgTagReceive);
}
while (bufid == 0);
if (bufid > 0) {
int bytes; int msgtag; int tid;
pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
pvm_recv(tid, msgtag);
pop[pop.size()-counter].pvm_upkind();
counter--;
}
}
}
void pvmSlaveReceiveSend(char* PVM_groupname,
const int PVM_groupsize,
const int PVM_MasterID ,
const int msgTagExit ,
const int msgTagSend ,
const int msgTagReceive,
const Interval RangeOfValues,
const unsigned NumOfBits ,
const bool UseGrayCode
)
{
int bufid, bufidExit = 0;
while (bufidExit == 0) {
do {
bufid = pvm_probe(pvm_gettid(PVM_groupname, PVM_MasterID), msgTagReceive);
bufidExit = pvm_probe(pvm_gettid(PVM_groupname, PVM_MasterID), msgTagExit) ;
if (bufidExit != 0)
pvm_recv(pvm_gettid(PVM_groupname, PVM_MasterID), msgTagExit) ;
}
while ((bufid == 0) && (bufidExit == 0));
if (bufid != 0) {
int bytes; int msgtag; int tid;
pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
Individual ind(ChromosomeT<bool>(1));
pvm_recv(tid, msgtag);
ind.pvm_upkind();
ChromosomeT< double > dblchrom;
dblchrom.decodeBinary(ind[ 0 ], RangeOfValues, NumOfBits, UseGrayCode);
ind.setFitness(sphere(dblchrom));
pvm_initsend(PvmDataDefault);
ind.pvm_pkind();
pvm_send(tid, msgTagSend);
}
}
}