//maxtime in seconds ExperimentResult iterativeLocalSearch(int size, int perturbationSize, Chromosome::GenerationType genType, int maxIterations = 50, time_t maxTime = -1) { // ofstream ILSsolution; // ILSsolution.open("ILSsolution.txt"); double maxDeviation = 1.2; Chromosome candidate = Chromosome(size, genType); candidate.swapNodesOpt(); Chromosome bestSolution(candidate); time_t endTime = time(0) + maxTime; if (maxTime < 0){ endTime = numeric_limits<long>::max(); } if (maxIterations < 0){ maxIterations = numeric_limits<int>::max(); } int i = 0; while (maxIterations > i && time(0) < endTime) { candidate.mutate(perturbationSize); candidate.swapNodesOpt(); //if the score is very bad -> use the old optimal solution to perturbate from if (candidate._score < bestSolution._score){ bestSolution = candidate; } else if (candidate._score > bestSolution._score * maxDeviation){ candidate = bestSolution; } // ILSsolution << candidate << endl; i++; } // ILSsolution.close(); ExperimentResult result; result.bestScore = bestSolution._score; result.iterations = i; return result; }
ExperimentResult dynamicPathRelinking(int ESSize, int globalIter, int localIter, int dth, Chromosome::GenerationType genType, double truncate = 1, time_t maxTime = MAX_TIME) { // - construct elite set (ES) with size b solutions vector<Chromosome> es; for (int i = 0; i < ESSize; ++i) { Chromosome chrom(Chromosome::_nodeList.size(), genType); chrom.swapNodesOpt(); es.push_back(chrom); } sort(es.begin(), es.end(), [](const Chromosome & a, const Chromosome & b) {return a._score < b._score; }); // - sort ES by score time_t endTime = time(0) + maxTime; if (maxTime < 0){ endTime = numeric_limits<long>::max(); } int gi; for (gi = 0; gi < globalIter && time(0) < endTime; ++gi) { // or just set time limit // cout << "iteration: " << gi << endl; for (int li = 0; li < localIter; ++li) { // cout << "iteration: " << gi << " / " << li << endl; // cout << "gcrCalls: " << Chromosome::gcrCalls << endl; // - construct solution Chromosome x(Chromosome::_nodeList.size(), genType); // - local search x.swapNodesOpt(); // - random select xj from ES int j = rand() % ESSize; // - get best solution from PR // - local search and save to y // Chromosome y = Chromosome::PathRelink(x, es[j]); Chromosome y = Chromosome::GACrossOver(x, es[j]); y.swapNodesOpt(); if (y._score > x._score) { //uncomment for GACrossover y = x; } if (y._score < es[0]._score) { // - if the solution is better than the best in ES replace it es[0] = y; } else if (y._score < es[ESSize - 1]._score) { // - elseif solution is better than the worst in ES and hamming distance is smaller than dth bool addToEs = true; vector<int> distances(ESSize); for (int i = 0; i < ESSize; ++i) { distances[i] = Chromosome::distance(y, es[i]); if (distances[i] <= dth) { addToEs = false; break; } } if (addToEs) { // cout << "better ES member recombined" << endl; // find the closest solution in ES (by hamming distance) to y such that score y._score is better int swapId; int swapDistance = numeric_limits<int>::max();; for (int i = 0; i < ESSize; ++i) { if (y._score < es[i]._score) { if (distances[i] < swapDistance) { swapId = i; swapDistance = distances[i]; } } } // replace them es[swapId] = y; // sort ES sort(es.begin(), es.end(), [](const Chromosome & a, const Chromosome & b) {return a._score < b._score; }); } } } int map[30][30]; for (int k = 0; k < ESSize; ++k) { for (int i = 0; i < ESSize; ++i) { map[k][i] = 0; } } bool newSol = true; while (newSol) { newSol = false; for (int i = 0; i < ESSize; ++i) { for (int j = 0; j < ESSize / 2; ++j) { // not need to generate those that were generated before if (map[i][j] == 1) { continue; } else { map[i][j] = 1; } // cout << "combining " << i << " " << j << endl; Chromosome y = Chromosome::GACrossOver(es[i], es[j]); y.swapNodesOpt(); if (y._score < es[0]._score) { // - if the solution is better than the best in ES replace it es[0] = y; newSol = true; } else if (y._score < es[ESSize - 1]._score) { // - elseif solution is better than the worst in ES and hamming distance is smaller than dth bool addToEs = true; vector<int> distances(ESSize); for (int i = 0; i < ESSize; ++i) { distances[i] = Chromosome::distance(y, es[i]); if (distances[i] <= dth) { addToEs = false; break; } } if (addToEs) { // find the closest solution in ES (by hamming distance) to y such that score y._score is better int swapId; int swapDistance = numeric_limits<int>::max();; for (int i = 0; i < ESSize; ++i) { if (y._score < es[i]._score) { if (distances[i] < swapDistance) { swapId = i; swapDistance = distances[i]; } } } // replace them es[swapId] = y; // sort ES sort(es.begin(), es.end(), [](const Chromosome & a, const Chromosome & b) {return a._score < b._score; }); newSol = true; } } } } } } // // for (int k = 0; k < ESSize; ++k) { // cout << es[k] << endl; // } ExperimentResult result; result.bestScore = es[0]._score; result.iterations = gi; // cout << "valid: " << es[0] << endl; return result; }