commit 24928d67a2807f940ce4feae7dafddaded8eafee
parent b63726e7909eac79b536506b693166288ec9dc4d
Author: Marc Jeanmougin <marc@jeanmougin.fr>
Date: Thu, 10 Apr 2014 01:29:35 +0200
utility
Diffstat:
2 files changed, 754 insertions(+), 0 deletions(-)
diff --git a/contest/mehdi/a.cpp b/contest/mehdi/a.cpp
@@ -629,6 +629,7 @@ int main(int argc, char *argv[]) {
ameliore = 0;
prev_amel = amel;
+ #pragma omp parallel for
for (int v = 0; v < n_vehicules; v++)
ameliore |= amel[v] = ajoute_fin(v) || (!prev_amel[v] && ajoute_force(v));
diff --git a/contest/mehdi/b.cpp b/contest/mehdi/b.cpp
@@ -0,0 +1,753 @@
+
+#include <csignal>
+#include <bitset>
+#include <numeric>
+#include <map>
+#include "../louis/louis.cpp"
+//#include "../mc/lecture.cpp"
+#include "../mc/prune.cpp"
+#include "../louis/ameliore.cpp"
+
+typedef pair<int, vector<int> > pivi;
+typedef unsigned int uint;
+
+// ATTENTION: 3 globales maintenues à jour tout le temps, faites pas de conneries !
+int score = 0;
+int temps[8];
+int passages[N_ARETES_MAJ];
+
+// const int MAX_RM = 7;
+// const int MAX_ADD = 7;
+uint MAX_RM = 4;
+uint MAX_ADD = 4;
+const int MAX_GIT = 20;
+volatile bool interrupted = false;
+
+bool force_affiche_interm = false;
+void intHandler(int sig) {
+ if (interrupted) {
+ fprintf(stderr, "Ok, ok, j'ai compris\n");
+ exit(0);
+ } else if (force_affiche_interm) {
+ fprintf(stderr, "Will terminate soon(ish)... ^C à nouveau pour vraiment quitter (pas de sortie)\n");
+ interrupted = true;
+ } else {
+ fprintf(stderr, "Je vais écrire une solution intermédiaire. ^C à nouveau pour quitter\n");
+ force_affiche_interm = true;
+ }
+}
+
+void affiche_score() {
+ for (int v = 0; v < n_vehicules; v++)
+ fprintf(stderr, "t[%d] = %d\n", v, temps[v]);
+ fprintf(stderr, "score = %d\n", score);
+}
+
+void affiche() {
+ affiche_score();
+ affiche_sortie(_solution);
+}
+
+int nbinterm = 0;
+char interm_filename[255];
+char *interm_basename;
+void affiche_interm() {
+ sprintf(interm_filename, "%s_%05d", interm_basename, nbinterm);
+ affiche_sortie(_solution, interm_filename);
+ affiche_score();
+ fprintf(stderr, "\t\t\t\t\t\t\t\tPRINT %s\n", interm_filename);
+ nbinterm++;
+}
+
+inline void check_interrupt() {
+ if (force_affiche_interm) {
+ affiche_interm();
+ force_affiche_interm = false;
+ }
+
+ if (interrupted) {
+ affiche();
+ exit(0);
+ }
+}
+
+bool ajoute_fin(int v) {
+ int cur = _solution[v].back();
+ for (uint i = 0; i < adj[cur].size(); i++) {
+ int voisin = adj[cur][i];
+ int arete = id_arete[make_pair(cur, voisin)];
+ if (passages[arete])
+ continue;
+ if (temps[v] + cout[arete] > t_autorise)
+ continue;
+ _solution[v].push_back(voisin);
+ temps[v] += cout[arete];
+ if (!passages[arete])
+ score += longueur[arete];
+ passages[arete]++;
+ fprintf(stderr, "%d\t+%d\tAjoute fin %d à vehicule %d (t = %d)\n", score, longueur[arete] * (passages[arete] == 1), voisin, v, temps[v]);
+ return true;
+ }
+ return false;
+}
+
+#ifdef AJOUTEFORCE
+bool ajoute_force(int v) {
+ int cur = _solution[v].back();
+ uint deg = adj[cur].size();
+ bitset<N_DEGRE_MAJ> a;
+ uint remaining = deg;
+ while (remaining) {
+ uint i = rand() % deg;
+ if (a[i])
+ continue;
+ a[i] = true;
+ remaining--;
+
+ int voisin = adj[cur][i];
+ int arete = id_arete[make_pair(cur, voisin)];
+ if (temps[v] + cout[arete] > t_autorise)
+ continue;
+ _solution[v].push_back(voisin);
+ temps[v] += cout[arete];
+ if (!passages[arete])
+ score += longueur[arete];
+ passages[arete]++;
+ fprintf(stderr, "%d\t+%d\tAjoute force fin %d à vehicule %d (t = %d)\n", score, longueur[arete] * (passages[arete] == 1), voisin, v, temps[v]);
+ return true;
+ }
+ return false;
+}
+#else
+bool ajoute_force(int v) { return false; }
+#endif
+
+void mul_pos(int v, uint i, int mul) {
+ // fprintf(stderr, "mul_pos %d %d %d\n", v, i, mul);
+ int arete = id_arete[make_pair(_solution[v][i], _solution[v][i+1])];
+ temps[v] += cout[arete] * mul;
+ if (!passages[arete])
+ score += longueur[arete];
+ passages[arete] += mul;
+ if (!passages[arete])
+ score -= longueur[arete];
+}
+
+pivi cherche_modif(int v, int debut, int fin, int max_add, int score_a_battre, int temps_a_battre) {
+ pivi best;
+ best.first = -1;
+ for (uint i = 0; i < adj[debut].size(); i++) {
+ int voisin = adj[debut][i];
+ if (nb_aretes[voisin][fin] > max_add)
+ continue;
+ // if (!max_add && voisin != fin)
+ // continue;
+ int arete = id_arete[make_pair(debut, voisin)];
+ if (temps[v] + cout[arete] > t_autorise)
+ continue;
+ if (!passages[arete])
+ score += longueur[arete];
+ if (!max_add) {
+ if (score > score_a_battre || (score == score_a_battre && temps[v] + cout[arete] < temps_a_battre)) {
+ // fprintf(stderr, "%d > %d (%d -> %d)\n", score, score_a_battre, debut, fin);
+ best.first = score;
+ best.second.push_back(fin);
+ }
+ if (!passages[arete])
+ score -= longueur[arete];
+ return best;
+ }
+ passages[arete]++;
+ temps[v] += cout[arete];
+ pivi cur = cherche_modif(v, voisin, fin, max_add - 1, score_a_battre, temps_a_battre);
+ if (cur.first > best.first) {
+ best = cur;
+ best.second.push_back(voisin);
+ // fprintf(stderr, "add to best %d -> %d\n", debut, voisin);
+ }
+ temps[v] -= cout[arete];
+ passages[arete]--;
+ if (!passages[arete])
+ score -= longueur[arete];
+ }
+ return best;
+}
+
+void debug_car(int v) {
+ fprintf(stderr, "Car %d\tt %d :\n ", v, temps[v]);
+ for (uint i = 0; i < _solution[v].size(); i++)
+ fprintf(stderr, "%d ", _solution[v][i]);
+ fprintf(stderr, "\n");
+}
+
+bool modif(int v) {
+ bool didit = false;
+ for (uint rm = 0; rm <= MAX_RM; rm++) {
+ check_interrupt();
+ for (int pos = int(_solution[v].size()) - rm - 1 ; pos >= 0; pos--) {
+ if (pos + rm + 1 > _solution[v].size())
+ continue;
+ int prev_score = score;
+ int prev_temps = temps[v];
+ for (uint dp = 0; dp < rm; dp++)
+ mul_pos(v, pos + dp, -1);
+ pivi mod = cherche_modif(v, _solution[v][pos], _solution[v][pos+rm], MAX_ADD, prev_score, prev_temps);
+ if (mod.first < 0) {
+ for (uint dp = 0; dp < rm; dp++)
+ mul_pos(v, pos + dp, 1);
+ continue;
+ }
+ // debug_car(v);
+ _solution[v].erase(_solution[v].begin() + pos + 1, _solution[v].begin() + pos + 1 + rm);
+ // debug_car(v);
+ _solution[v].insert(_solution[v].begin() + pos + 1, mod.second.rbegin(), mod.second.rend());
+ // debug_car(v);
+ for (uint j = 0; j < mod.second.size(); j++)
+ mul_pos(v, pos + j, 1);
+ int dt = temps[v] - prev_temps;
+ fprintf(stderr, "%d\t+%d\tModif longueur %zu (rm %d) à vehicule %d pos %d (t %c= %d)\n", score, score - prev_score, mod.second.size(), rm, v, pos, dt > 0 ? '+' : '-', dt > 0 ? dt : -dt);
+ if (score < prev_score || (score == prev_score && dt > 0)) {
+ debug_car(v);
+ exit(0);
+ }
+ didit = true;
+ //return true;
+ }
+ }
+ return didit;
+}
+
+#ifdef DEBUG
+void debug_sol() {
+ vector<int> T = evalue_solution(_solution);
+ fprintf(stderr, "Score %d (vs %d)\n", score, T[0]);
+ for (int v = 0; v < n_vehicules; v++) {
+ fprintf(stderr, "Car %d\tt %d (vs %d) :\n ", v, temps[v], T[v+1]);
+ for (uint i = 0; i < _solution[v].size(); i++) {
+ fprintf(stderr, " %d", _solution[v][i]);
+#ifdef DEBUGA
+ if (i < _solution[v].size() - 1) {
+ int arete = id_arete[make_pair(_solution[v][i], _solution[v][i+1])];
+ fprintf(stderr, " [t %d]", cout[arete]);
+ }
+#endif
+ }
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+}
+#else
+#define debug_sol()
+#endif
+
+/*
+int order[8] = {0,1,2,3,4,5,6,7};
+
+void prune() {
+ random_shuffle(order, order+n_vehicules);
+ for (int i = 0; i < n_vehicules; i++) {
+ int v = order[i];
+ int skipped_last = 0;
+ vector<int> res(1, _solution[v][0]);
+
+ }
+}*/
+
+void calc_glob() {
+ vector<int> T = evalue_solution(_solution);
+ score = T[0];
+ memset(passages,0,sizeof(passages));
+ for (int v = 0; v < n_vehicules; v++) {
+ temps[v] = T[v+1];
+ for (uint i = 0; i < _solution[v].size() - 1; i++) {
+ int arete = id_arete[make_pair(_solution[v][i], _solution[v][i+1])];
+ passages[arete]++;
+ }
+ }
+}
+
+int temps_total() {
+ return accumulate(temps, temps+n_vehicules, 0);
+}
+
+int order[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+bool prune_and_complete() {
+ random_shuffle(order, order+n_vehicules);
+
+ int prev_temps = temps_total();
+ int prev_score = score;
+ memset(passages, 0, sizeof(passages));
+ score = 0;
+ for (int iv = 0; iv < n_vehicules; iv++) {
+ int v = order[iv];
+ temps[v] = 0;
+ bool skipped_last = false;
+ vector<int> res;
+ res.push_back(_solution[v][0]);
+ for (uint i = 0; i < _solution[v].size() - 1; i++) {
+ int a = id_arete[make_pair(_solution[v][i], _solution[v][i+1])];
+ if (!a) {
+ fprintf(stderr, "ERREUR");
+ exit(1);
+ }
+ if (!passages[a]) {
+ if (skipped_last) {
+ while (res.back() != _solution[v][i]) {
+ int n = use[res.back()][_solution[v][i]];
+ int b = id_arete[make_pair(res.back(), n)];
+ if (!passages[b])
+ score += longueur[b];
+ passages[b]++;
+ temps[v] += cout[b];
+ res.push_back(n);
+ }
+ }
+ res.push_back(_solution[v][i+1]);
+ if (!passages[a])
+ score += longueur[a];
+ passages[a]++;
+ temps[v] += cout[a];
+ skipped_last = false;
+ } else {
+ skipped_last = true;
+ }
+ }
+ /*
+ if (skipped_last) {
+ while (res.back() != _solution[v].back()) {
+ int n = use[res.back()][_solution[v].back()];
+ int b = id_arete[make_pair(res.back(), n)];
+ if (!passages[b])
+ score += longueur[b];
+ passages[b]++;
+ temps[v] += cout[b];
+ res.push_back(n);
+ }
+ }
+ */
+ _solution[v] = res;
+ }
+ int dt = prev_temps - temps_total();
+ int ds = score - prev_score;
+ if (dt < 0 || ds < 0) {
+ fprintf(stderr, "Failed to prune correctly, t -= %d\tscore += %d\n", dt, ds);
+ //exit(1);
+ } else if (dt || ds) {
+ fprintf(stderr, "Pruned! t -= %d\tscore += %d\n", dt, ds);
+ return true;
+ }
+ return false;
+}
+
+/*
+ <X> A B <Y> B A <Z> A B <T>
+ ->
+ <X> A <Z> A B <Y> B <T>
+
+ <X> B A <Y> A B <Z> A B <T>
+ ->
+ <X> B <Z> A <Y> A B <T>
+ */
+bool simplif_elarnon(vector<int> sol[], int v) {
+ short posa[2][N_ARETES_MAJ];
+ memset(posa, 0, sizeof(posa));
+
+ for (uint i = 0; i < sol[v].size() - 1; i++) {
+ int a = id_arete[make_pair(sol[v][i], sol[v][i+1])];
+ int sens = sol[v][i] == depart[a];
+ if (posa[sens][a] && posa[!sens][a]) {
+ temps[v] -= 2 * cout[a];
+ passages[a] -= 2;
+ vector<int> res;
+ //fprintf(stderr, "elarnon pos %u/%zu arete %d, deja utilise en %d et %d\n", i, sol[v].size(), a, posa[sens][a]-1, posa[!sens][a]-1);
+ if (posa[sens][a] < posa[!sens][a]) {
+ res.insert(res.end(), sol[v].begin(), sol[v].begin() + posa[sens][a]); // <X> A
+ res.insert(res.end(), sol[v].begin() + posa[!sens][a] + 1, sol[v].begin() + i + 2); // <Z> A B
+ res.insert(res.end(), sol[v].begin() + posa[sens][a] + 1, sol[v].begin() + posa[!sens][a]); // <Y> B
+ res.insert(res.end(), sol[v].begin() + i + 2, sol[v].end()); // <T>
+ } else {
+ res.insert(res.end(), sol[v].begin(), sol[v].begin() + posa[!sens][a]); // <X> B
+ res.insert(res.end(), sol[v].begin() + posa[sens][a] + 1, sol[v].begin() + i + 1); // <Z> A
+ res.insert(res.end(), sol[v].begin() + posa[!sens][a] + 1, sol[v].begin() + posa[sens][a] + 1); // <Y> A B
+ res.insert(res.end(), sol[v].begin() + i + 2, sol[v].end()); // <T>
+ }
+ sol[v] = res;
+ return true;
+ }
+ posa[sens][a] = i+1;
+ }
+ return false;
+}
+
+bool simplif_elarnon() {
+ int prev_temps = temps_total();
+ random_shuffle(order, order+n_vehicules);
+ bool r = false;
+ for (int i = 0; i < n_vehicules; i++) {
+ int v = order[i];
+ r |= simplif_elarnon(_solution, v);
+ }
+ if (r) {
+ int dt = prev_temps - temps_total();
+ fprintf(stderr, "Elarnon in action, t -= %d\n", dt);
+ }
+ return r;
+}
+
+void vraie_etoile(vector<int> sol[]) {
+
+ bool ameliore = true;
+ double d[n_vehicules];
+ fill(d, d+n_vehicules, 0.0);
+ while (ameliore) {
+ ameliore = false;
+ for (int v = 0; v < n_vehicules; v++) {
+ double best = -42.0;
+ int bestVoisin = -1;
+ int bestArete = -1;
+ int cur = sol[v].back();
+ for (uint i = 0; i < adj[cur].size(); i++) {
+ int voisin = adj[cur][i];
+ int a = id_arete[make_pair(cur, voisin)];
+ if (temps[v] + cout[a] > t_autorise)
+ continue;
+ double mi = 19840000.0;
+ for (int w = 0; w < n_vehicules; w++)
+ if (v != w) {
+#ifdef JUSTHEAD
+ int wcur = sol[w].back();
+#else
+ for (uint j = 0; j < sol[w].size(); j++) {
+ int wcur = sol[w][j];
+#endif
+ mi = min(mi, hypot(longitude[voisin] - longitude[wcur],
+ latitude[voisin] - latitude[wcur]));
+#ifndef JUSTHEAD
+ }
+#endif
+ }
+#ifdef LONDONISBAD
+ mi = min(mi, hypot(longitude[voisin] - longitude[s_depart],
+ latitude[voisin] - latitude[s_depart]));
+#endif
+ if (mi > best) {
+ best = mi;
+ bestVoisin = voisin;
+ bestArete = a;
+ }
+ }
+ if (bestVoisin < 0)
+ continue;
+ //fprintf(stderr, "Etoile v %d, go to %d, dist %lf\n", v, bestVoisin, best);
+ if (best > d[v]) {
+ ameliore = true;
+ d[v] = best;
+ }
+#ifdef BRUTETOILE
+ d[v] = best;
+#endif
+ sol[v].push_back(bestVoisin);
+ temps[v] += cout[bestArete];
+ if (!passages[bestArete])
+ score += longueur[bestArete];
+ passages[bestArete]++;
+ }
+ }
+}
+
+void positions_choisies() {
+ _solution[0].push_back(plus_proche(48.848451,2.263328));
+ _solution[1].push_back(plus_proche(48.836136,2.289421));
+ _solution[2].push_back(plus_proche(48.825401,2.334568));
+ _solution[3].push_back(plus_proche(48.830939,2.377998));
+ _solution[4].push_back(plus_proche(48.862004,2.407696));
+ _solution[5].push_back(plus_proche(48.88673,2.394306));
+ _solution[6].push_back(plus_proche(48.897791,2.357399));
+ _solution[7].push_back(plus_proche(48.886053,2.288048));
+}
+
+inline double dist(int s1, int s2) {
+ return hypot(longitude[s1] - longitude[s2], latitude[s1] - latitude[s2]);
+}
+
+void gloutonne() {
+ const double INF = 123456789.0;
+ int GLOUTONNE_MAX = n_aretes;
+ vector<pair<int, int> > ar;
+ for (int a = 1; a <= n_aretes; a++)
+ ar.push_back(make_pair(longueur[a], a));
+ sort(ar.begin(), ar.end());
+ GLOUTONNE_MAX = min(GLOUTONNE_MAX, int(ar.size()));
+ for (int i = 0; i < GLOUTONNE_MAX; i++) {
+ int a = ar[i].second;
+ if (passages[a])
+ continue;
+ double d[n_vehicules];
+ bool o[n_vehicules];
+ uint p[n_vehicules];
+ for (int v = 0; v < n_vehicules; v++) {
+ d[v] = INF;
+ if (temps[v] >= t_autorise)
+ continue;
+ for (uint j = 0; j < _solution[v].size(); j++) {
+ double f = dist(_solution[v][j], depart[a]);
+ if (f < d[v]) {
+ d[v] = f;
+ o[v] = false;
+ p[v] = j;
+ }
+ if (dbsens[a]) {
+ double e = dist(_solution[v].back(), arrivee[a]);
+ if (e < d[v]) {
+ d[v] = e;
+ o[v] = true;
+ p[v] = j;
+ }
+ }
+ }
+ }
+ int v = min_element(d, d + n_vehicules) - d;
+ if (d[v] == INF)
+ break;
+ int go;
+ if (o[v])
+ go = arrivee[a];
+ else
+ go = depart[a];
+ fprintf(stderr, "Gloutonne, vehicule %d, pos %u va à %d pour arête %d\n", v, p[v], go, a);
+ vector<int> toinsert;
+ toinsert.push_back(_solution[v][p[v]]);
+ while (toinsert.back() != go) {
+ int u = use[toinsert.back()][go];
+ int b = id_arete[make_pair(toinsert.back(), u)];
+ if (!passages[b])
+ score += longueur[b];
+ passages[b]++;
+ temps[v] += cout[b];
+ toinsert.push_back(u);
+ }
+ if (p[v] < _solution[v].size() - 1) {
+ if (!passages[a]) {
+ toinsert.push_back(go == arrivee[a] ? depart[a] : arrivee[a]);
+ temps[v] += cout[a];
+ score += longueur[a];
+ }
+ passages[a]++;
+ go = _solution[v][p[v]];
+ while (toinsert.back() != go) {
+ int u = use[toinsert.back()][go];
+ int b = id_arete[make_pair(toinsert.back(), u)];
+ if (!passages[b])
+ score += longueur[b];
+ passages[b]++;
+ temps[v] += cout[b];
+ toinsert.push_back(u);
+ }
+ }
+ _solution[v].erase(_solution[v].begin() + p[v]);
+ _solution[v].insert(_solution[v].begin() + p[v], toinsert.begin(), toinsert.end());
+ }
+}
+
+bool try_ameliore_louis() {
+ int prev_score = score;
+ ameliore_louis(_solution);
+ calc_glob();
+ if (score > prev_score) {
+
+ fprintf(stderr, "Merci Louis ! (score += %d)\n", score - prev_score);
+ return true;
+ }
+ if (prev_score > score) {
+ fprintf(stderr, "Louis, tu fais de la merde (score -= %d)\n", prev_score - score);
+ exit(1);
+ }
+ fprintf(stderr, "Louis, inutile !\n");
+ return false;
+}
+
+void print_stats() {
+ map<int, int> nb_passages;
+ for (int a = 1; a <= n_aretes; a++)
+ nb_passages[passages[a]]++;
+ int m = nb_passages.rbegin()->first;
+ for (int p = 0; p <= m; p++)
+ fprintf(stderr, "%d route%s à %d passage%s\n", nb_passages[p], nb_passages[p] >= 2 ? "s" : "", p, p >= 2 ? "s" : "");
+}
+
+int main(int argc, char *argv[]) {
+ /*
+ Usage: a.out [INTERM_BASENAME [INIT_SOLUTION]]
+ INTERM_BASENAME: nom de base pour écrire les solutions intermédiaires
+ INIT_SOLUTION: nom du fichier de la solution initiale
+ */
+
+ signal(SIGINT, intHandler);
+
+ srand(time(NULL));
+ lecture_entree();
+ init_use();
+ init_nb_aretes();
+
+ if (argc > 2)
+ lire_solution(argv[2], _solution);
+ else {
+ init_solution(_solution);
+ // vraie_etoile(_solution);
+#ifdef CHOIZ
+ positions_choisies();
+ complete_all(_solution);
+#endif
+#ifdef GLOUTONNE
+ gloutonne();
+ tronque_solution(_solution);
+#endif
+ }
+
+ calc_glob();
+ affiche_score();
+ print_stats();
+
+ debug_sol();
+ prune_and_complete();
+ debug_sol();
+
+ bool ameliore = true;
+ bitset<8> prev_amel, amel;
+
+ fprintf(stderr, "C'est parti...\n");
+
+ if (argc > 1)
+ interm_basename = argv[1];
+
+while(1){
+
+int go=1;
+//
+ vector<int> time[8];
+ for(int i=0;i<8;i++){
+ int t=0;
+ time[i].push_back(0);
+ for(int j=0;j<_solution[i].size()-1;j++){
+ t+=cout[id_arete[make_pair(_solution[i][j],_solution[i][j+1])]];
+ time[i].push_back(t);
+//
+
+}}
+
+// for(int i=0;i<7 && go;i++){i=3;
+int i=0;int mmax=time[i][time[i].size()-1];int mmin=time[i][time[i].size()-1];
+ for(int x=0;x<8;x++){
+ int a=time[x][time[x].size()-1];
+ if(a>mmax){mmax=a;i=x;}
+ if(a<mmin){mmin=a;}
+ }
+ fprintf(stderr,"max,min %d %d\n",mmax,mmin);
+
+ if(mmax-mmin<1){affiche();return 0;}
+// if(mmax<53720){affiche();return 0;}
+
+ for(int j=0;j<8 && go ;j++){
+if(j==i)continue;
+
+ check_interrupt();
+ fprintf(stderr,"trying %d %d\n",i,j);
+ //foreach pair of cars
+
+ vector<int> comm_i;
+ vector<int> comm_j;
+
+ for(int xx=0;xx<_solution[i].size();xx++)
+ for(int yy=0;yy<_solution[j].size();yy++){
+ if(_solution[i][xx]==_solution[j][yy]){
+ comm_i.push_back(xx);comm_j.push_back(yy);
+ }
+ }
+ fprintf(stderr,"comm= %d %d\n",comm_i.size(),comm_j.size());
+
+ for(int ii1=0;ii1<comm_i.size() && go;ii1++){
+ for(int jj1=0;jj1<comm_j.size()&& go;jj1++){
+ int i1=comm_i[ii1];
+ int j1=comm_j[jj1];
+ if(_solution[i][i1]!=_solution[j][j1])continue;
+ for(int ii2=ii1+1;ii2<comm_i.size()&& go;ii2++){
+// fprintf(stderr,"... %d %d\n",ii1,jj1);
+ for(int jj2=jj1+1;jj2<comm_j.size()&& go;jj2++){
+ int i2=comm_i[ii2];
+ int j2=comm_j[jj2];
+ if(_solution[i][i2]!=_solution[j][j2])continue;
+ if(i2<i1 or j2<j1)continue;
+
+ int ti=time[i][time[i].size()-1];
+ int tj=time[j][time[j].size()-1];
+
+ int ti1=time[i][i1];
+ int ti2=time[i][i2];
+ int tj1=time[j][j1];
+ int tj2=time[j][j2];
+
+ //exchange paths ?
+ int ex=0;
+ if(ti<tj){
+ if(ti2-ti1 < tj2-tj1 && ti-(ti2-ti1)+(tj2-tj1)<tj && tj-(tj2-tj1)+(ti2-ti1)<tj ){ex=1;}
+ }else{
+ if(ti2-ti1 > tj2-tj1 && ti-(ti2-ti1)+(tj2-tj1)<ti && tj-(tj2-tj1)+(ti2-ti1)<ti ){ex=1;}
+ }
+ if(ex){
+ go=0;
+ fprintf(stderr,"would exchange %d between %d : %d %d (%d)and %d : %d %d(%d)\n",ti2-ti1-tj2+tj1,i,i1,i2,ti,j,j1,j2,tj);
+
+ //i1..i2 <-> j1..j2
+ vector<int> newi;
+ vector<int> newj;
+ for(int x=0;x<i1;x++)newi.push_back(_solution[i][x]);
+ for(int x=j1;x<j2;x++)newi.push_back(_solution[j][x]);
+ for(int x=i2;x<_solution[i].size();x++)newi.push_back(_solution[i][x]);
+
+ for(int x=0;x<j1;x++)newj.push_back(_solution[j][x]);
+ for(int x=i1;x<i2;x++)newj.push_back(_solution[i][x]);
+ for(int x=j2;x<_solution[j].size();x++)newj.push_back(_solution[j][x]);
+ _solution[i]=newi;
+ _solution[j]=newj;
+// affiche();return 0;
+// goto lab;
+ }
+
+ }}}}
+
+ }
+ if(go){break;}
+ //}
+}//while1
+lab:
+/* for (int git = 0; git < MAX_GIT; git++) {
+ ameliore = 1;
+ for (; ameliore; it++) {
+ debug_sol();
+
+ ameliore = 0;
+ prev_amel = amel;
+ #pragma omp parallel for
+ for (int v = 0; v < n_vehicules; v++)
+ ameliore |= amel[v] = ajoute_fin(v) || (!prev_amel[v] && ajoute_force(v));
+
+ check_interrupt();
+
+ debug_sol();
+ for (int v = 0; v < n_vehicules; v++)
+ ameliore |= amel[v] = amel[v] || modif(v);
+
+ ameliore |= prune_and_complete();
+ ameliore |= simplif_elarnon();
+
+ check_interrupt();
+ // if (!ameliore)
+ // ameliore = try_ameliore_louis();
+ }
+ MAX_ADD++;
+ MAX_RM+=2;
+ }*/
+
+ affiche();
+}