ECF 1.5
TSPEvalOp.cpp
1#include <cmath>
2#include <iostream>
3#include <string>
4#include <fstream>
5#include <ecf/ECF.h>
6#include "TSPEvalOp.h"
7
8
10{
11 state->getRegistry()->registerEntry("tsp.infile", (voidP) (new std::string), ECF::STRING);
12}
13
14
15bool TSPEvalOp::initialize(StateP state)
16{
17 if(!state->getRegistry()->isModified("tsp.infile")) {
18 state->getLogger()->log(1, "Error: no input file defined for TSP! (parameter 'tsp.infile'");
19 return false;
20 }
21
22 voidP sptr = state->getRegistry()->getEntry("tsp.infile"); // get parameter value
23 std::string filePath = *((std::string*) sptr.get()); // convert from voidP to user defined type
24
25 std::ifstream iFile(filePath.c_str());
26 std::string line;
27 if(!iFile.is_open()) {
28 state->getLogger()->log(1, "Error: can't open input file " + filePath);
29 return false;
30 }
31
32 // read dimension (number of cities)
33 do {
34 getline(iFile,line);
35 }while(line.find("DIMENSION",0) == std::string::npos);
36 std::stringstream ss(line.substr(line.find(":") + 1));
37 ss >> dimension;
38
39 // set dimension for permutation genotype
40 state->getRegistry()->modifyEntry("Permutation.size", (voidP) new uint(dimension));
41
42 // reinitialize population with updated size
43 state->getPopulation()->initialize(state);
44
45 // parse TSP data type
46 do {
47 getline(iFile,line);
48 }while(line.find("EDGE_WEIGHT_TYPE",0) == std::string::npos);
49 std::stringstream ss_type(line.substr(line.find(":") + 1));
50 string dataType;
51 ss_type >> dataType;
52
53 if(dataType == "EUC_2D") {
54
55 // read coordinates, calculate euclidian distances
56 do {
57 getline(iFile,line);
58 }while(line.find("NODE_COORD_SECTION",0) == std::string::npos);
59
60 coordinates.resize(dimension);
61 for(int i = 0; i < dimension; i++) {
62 coordinates[i].resize(2);
63 double datum;
64 iFile >> datum;
65 iFile >> coordinates[i][0];
66 iFile >> coordinates[i][1];
67 }
68
69 weights.resize(dimension);
70 for(int i = 0; i < dimension; i++) {
71 weights[i].resize(dimension);
72 for(int j = 0; j < dimension; j++) {
73 double diffX = coordinates[i][0] - coordinates[j][0];
74 double diffY = coordinates[i][1] - coordinates[j][1];
75 weights[i][j] = (int) (0.5 + sqrt(1. * diffX * diffX + diffY * diffY));
76 }
77 }
78 return true;
79
80 } else if (dataType == "EXPLICIT") {
81 do {
82 getline(iFile,line);
83 }while(line.find("EDGE_WEIGHT_FORMAT",0) == std::string::npos);
84 std::stringstream ss_format(line.substr(line.find(":") + 1));
85 string dataFormat;
86 ss_format >> dataFormat;
87 if(dataFormat == "FULL_MATRIX") {
88 // read distances in full matrix form
89 do {
90 getline(iFile,line);
91 }while(line.find("EDGE_WEIGHT_SECTION",0) == std::string::npos);
92
93 weights.resize(dimension);
94 for(int i = 0; i < dimension; i++) {
95 weights[i].resize(dimension);
96 for(int j = 0; j < dimension; j++) {
97 iFile >> weights[i][j];
98 }
99 }
100 return true;
101 }
102
103 }
104
105 // if all fails:
106 // unrecognized TSP data type
107 state->getLogger()->log(1, "TSP initializer: can't recognize TSP data in " + filePath
108 + "\n(supported TSP instances: \n\t- type \"EDGE_WEIGHT_TYPE: EUC_2D\" \n\t- type \"EDGE_WEIGHT_TYPE: EXPLICIT\" with "
109 + "\"EDGE_WEIGHT_FORMAT: FULL_MATRIX\")");
110 return false;
111}
112
113
114FitnessP TSPEvalOp::evaluate(IndividualP individual)
115{
116 // minimize travel distance, so use FitnessMin
117 FitnessP fitness (new FitnessMin);
118
119 // get Permutation genotype from the individual
120 Permutation::Permutation* perm = (Permutation::Permutation*) individual->getGenotype().get();
121 // (you can also use boost smart pointers:)
122 //PermutationP perm = boost::static_pointer_cast<Permutation::Permutation> (individual->getGenotype());
123
124 int fitnessV = 0;
125 // genotype Permutation keeps a vector of indexes named 'variables'
126 uint size = (uint) perm->variables.size();
127 for(uint i = 0; i < size - 1; i++){
128 // the length of each route is the sum of distances (weights) between each city in a route
129 fitnessV += weights[perm->variables[i]][perm->variables[i + 1]];
130 }
131 fitnessV += weights[perm->variables[0]][perm->variables[dimension - 1]];
132
133 fitness->setValue(fitnessV);
134 return fitness;
135}
Fitness for minimization problems.
Definition: FitnessMin.h:12
Permutation class - implements genotype as a vector of indices 0..(n-1) (permutation of indices)
Definition: Permutation.h:37
bool initialize(StateP)
Initialize the evaluator. Called before first evaluation occurs.
Definition: TSPEvalOp.cpp:15
void registerParameters(StateP)
Register evaluator parameters. Called before EvaluateOp::initialize method.
Definition: TSPEvalOp.cpp:9
FitnessP evaluate(IndividualP individual)
Evaluate a single individual. Method must create and return a Fitness object.
Definition: TSPEvalOp.cpp:114