// 8.2 Renvoie un int dans l'intervalle [0..N[ // soit N valeurs différentes de 0 à N-1 int alea_int(int N) { return (int)(N*alea_float()); }
//============================================================== ARC_AROUND struct particle arc_around(struct swarm sw, struct particle p) { // Build a tour, asking opinion of other particles for each arc double big_value; int candidate[Nmax]; double candidate_penalty[Nmax]; int candidate_nb; double c_max; int i; int j; int k; //int m; int node1,node2; double penalty; struct particle pt; double r; int rank; int used[Nmax]= {0}; big_value=G.N*G.l_max; pt=p; node1=0; // The new tour begins in 0 rank=1; used[node1]=1; next_node: candidate_nb=0; for (node2=0; node2<G.N; node2++) // For each possible new node ... { if (used[node2]>0) continue; if(rank==G.N-1) goto set_node; // Last node => no choice, anyway penalty=0; for (j=0; j<sw.size; j++) // ... ask opinions { for (k=0; k<G.N-1; k++) // Find the arc in the current particle, if exists if (sw.p[k].best_x.s[k]==node1 && sw.p[k].best_x.s[k+1]==node2 ) { penalty=sw.p[k].best_f; goto next_opinions; } // Can't find it in the current particle penalty=big_value; next_opinions: ; } // Mean value candidate_penalty[candidate_nb]=penalty/sw.size; candidate[candidate_nb]=node2; candidate_nb=candidate_nb+1; } // next node2 // Choose the new node at random, according to penalties c_max=0; for (i=0; i<candidate_nb; i++) c_max=c_max+ candidate_penalty[i]; for (i=0; i<candidate_nb; i++) candidate_penalty[i]=1-candidate_penalty[i]/c_max; //Proba for (i=1; i<candidate_nb; i++) candidate_penalty[i]=candidate_penalty[i-1]+candidate_penalty[i]; // Cumulate r=alea_float(0,candidate_nb-1); // random choice //printf("\n %i: ",candidate_nb);for (i=0;i<candidate_nb;i++) printf(" %f", candidate_penalty[i]); for (i=0; i<candidate_nb; i++) { if(r<candidate_penalty[i]) { node2=candidate[i]; goto set_node; } } set_node: // printf("\n r %f, i %i node2 %i",r,i,node2); pt.x.s[rank]=node2; // Add the node used[node2]=1; // remember it is already used rank=rank+1; if (rank<G.N) goto next_node; pt.x.s[G.N]=pt.x.s[0]; // Complete the tour pt.f=f(pt,-1,-1); // evaluate if (pt.f<pt.best_f) // eventually update the best previous position { pt.best_x=pt.x; pt.best_f=pt.f; pt.best_time=time; } if (trace>1) { display_position(pt,1); display_position(pt,2); } BB_update(pt); // Update the blackboard return pt; }