|
@@ -1,7 +1,10 @@
|
|
|
#include "search.h"
|
|
|
#include <cmath>
|
|
|
#include <cassert>
|
|
|
+#include <algorithm> // sort
|
|
|
+#include <tuple> // tie, ignore
|
|
|
|
|
|
+using namespace std;
|
|
|
|
|
|
/********************** search ***********************/
|
|
|
|
|
@@ -69,9 +72,12 @@ void local_search::init() {
|
|
|
check();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
void local_search::random_neighbour() {
|
|
|
undoable = true;
|
|
|
+ _random_neighbour();
|
|
|
+}
|
|
|
+
|
|
|
+void local_search::_random_neighbour() {
|
|
|
i = rand()%dim;
|
|
|
int p = ha.get_p(i);
|
|
|
t1 = 1+rand()%(p-1);
|
|
@@ -85,6 +91,10 @@ void local_search::random_neighbour() {
|
|
|
void local_search::undo() {
|
|
|
assert(undoable);
|
|
|
undoable = false;
|
|
|
+ _undo();
|
|
|
+}
|
|
|
+
|
|
|
+void local_search::_undo() {
|
|
|
ha.get_pi(i).transpose(t1, t2);
|
|
|
}
|
|
|
|
|
@@ -115,7 +125,7 @@ bool random_local_search::accept(double previous, double current) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-/********************** sa_search ***********************/
|
|
|
+/********************** sa_local_search ***********************/
|
|
|
|
|
|
sa_local_search::sa_local_search(int dim, int npoints, int *p, double lambda, double temp)
|
|
|
:local_search(dim, npoints, p), lambda(lambda), temp(temp) {
|
|
@@ -130,3 +140,81 @@ bool sa_local_search::accept(double previous, double current) {
|
|
|
//printf("%lf\t%lf\n", temp, current);
|
|
|
return current < previous || (double)rand()/RAND_MAX < exp((previous - current)/temp);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+/********************** genetic_search ***********************/
|
|
|
+
|
|
|
+genetic_search::genetic_search(int dim, int npoints, int *p, int mu, int lambda, double c) :
|
|
|
+ search(dim, npoints, p), mu(mu), lambda(lambda), c(c) {
|
|
|
+ assert(mu > 0);
|
|
|
+ assert(lambda > 0);
|
|
|
+ assert(0 <= c && c <= 1);
|
|
|
+
|
|
|
+ filename = std::string("genetic_search_") + std::to_string(mu)
|
|
|
+ + "_" + std::to_string(lambda)
|
|
|
+ + "_" + std::to_string(c);
|
|
|
+
|
|
|
+ //init(); // not necessary here
|
|
|
+
|
|
|
+ genes.reserve(mu+lambda);
|
|
|
+ vector<permutation> base;
|
|
|
+
|
|
|
+ // basic vector of permutations
|
|
|
+ base.reserve(dim);
|
|
|
+ for(int i = 0; i < dim; i++)
|
|
|
+ base.emplace_back(p[i]);
|
|
|
+
|
|
|
+ // generate mu random genes
|
|
|
+ for(int i = 0; i < mu; i++) {
|
|
|
+ genes.push_back(make_pair(1., base));
|
|
|
+ for(int j = 0; j < dim; j++)
|
|
|
+ genes[i].second[j].random();
|
|
|
+ }
|
|
|
+
|
|
|
+ // "reserve" lambda other genes (later we'll only change permutations already
|
|
|
+ // created here)
|
|
|
+ for(int i = 0; i < lambda; i++)
|
|
|
+ genes.push_back(make_pair(1., base));
|
|
|
+}
|
|
|
+
|
|
|
+bool genes_ord(pair<double, vector<permutation>> &a, pair<double, vector<permutation>> &b) {
|
|
|
+ return a.first < b.first;
|
|
|
+}
|
|
|
+
|
|
|
+void genetic_search::_run(int iterations) {
|
|
|
+ for(int t = 0; t < iterations; t++) {
|
|
|
+ // generate lambda new genes
|
|
|
+ for(int i = 0; i < lambda; i++) {
|
|
|
+ vector<permutation> &gene = genes[mu+i].second;
|
|
|
+ if((double)rand()/RAND_MAX < c) {
|
|
|
+ // crossover
|
|
|
+ int g1 = rand()%mu, g2 = rand()%mu;
|
|
|
+ for(int d = 0; d < dim; d++)
|
|
|
+ gene[d] = permutation_crossover(genes[g1].second[d], genes[g2].second[d]);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // mutation from a gene
|
|
|
+ gene = genes[rand()%mu].second;
|
|
|
+ int id = rand()%dim;
|
|
|
+ int p = ha.get_p(id);
|
|
|
+ int t1 = 1+rand()%(p-1), t2 = 1+rand()%(p-2);
|
|
|
+ // ensure t1 != t2
|
|
|
+ if(t2 >= t1)
|
|
|
+ t2++;
|
|
|
+ gene[id].transpose(t1, t2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // for all gene
|
|
|
+ for(int i = 0; i < mu+lambda; i++) {
|
|
|
+ // replace permutations
|
|
|
+ // compute points
|
|
|
+ ha.set_pis(genes[i].second);
|
|
|
+ compute();
|
|
|
+ // compute discrepancy and check if it is good
|
|
|
+ check();
|
|
|
+ genes[i].first = current;
|
|
|
+ }
|
|
|
+ // sort genes : we want the mu firsts at the beginning
|
|
|
+ sort(genes.begin(), genes.end(), genes_ord);
|
|
|
+ }
|
|
|
+}
|