// This routine starts with some solution (current best or a random generated // solution) and iteratively perturb changing some nodes and applying 2OPT. bool TSP_Perturb2OPT(TSP_Data &tsp) { ListGraph *g; int nchanges,i,j; g = &tsp.g; vector<Node> Circuit(tsp.NNodes), BestCircuit(tsp.NNodes); double BestCircuitValue; //nchanges = 2 (tests with some instances indicate that nchanges=1 is better nchanges = 1; // Start with a initial solution (if there is no solution, generate any sequence) if (tsp.BestCircuitValue < DBL_MAX) { BestCircuitValue = tsp.BestCircuitValue; for (int i=0; i<tsp.NNodes; i++) BestCircuit[i] = tsp.BestCircuit[i]; } else { int i=0; BestCircuitValue = 0.0; for (ListGraph::NodeIt v(*g); v!=INVALID; ++v) BestCircuit[i++]=v; for (i=0;i<tsp.NNodes;i++) BestCircuitValue += tsp.AdjMat.Cost(BestCircuit[i] , BestCircuit[(i+1)%tsp.NNodes]); } for (int it=0;it<tsp.max_perturb2opt_it;it++) { if (!(it%100)) printf("[Heuristic: Perturbation+2OPT] it = %d (of %d)\n",it+1,tsp.max_perturb2opt_it); for (int k=0;k<tsp.NNodes;k++) Circuit[k] = BestCircuit[k]; for (int nc=0;nc<nchanges;nc++) { i = (int) (drand48()*tsp.NNodes); // get two random nodes and exchange j = (int) (drand48()*tsp.NNodes); // their positions if (i!=j) ChangeNode(Circuit[i],Circuit[j]); } Heuristic_2_OPT(tsp.AdjMat,Circuit,BestCircuitValue,tsp.NNodes); if (BestCircuitValue < tsp.BestCircuitValue) { //update the best circuit used tsp.BestCircuitValue = BestCircuitValue; // by the heuristic for (int i=0;i<tsp.NNodes;i++) { BestCircuit[i] = Circuit[i]; tsp.BestCircuit[i] = Circuit[i]; } } } return(true); }
void CharKeys (unsigned int key, bool special, bool release, int x, int y) { int keyfact; must_render = true; if (ToolsFinalStage ()) { if (key == SDLK_y || key == SDLK_j) { SaveToolCharacter (); SaveToolFrame (); Winsys.Quit(); } else if (key == SDLK_n) Winsys.Quit (); return; } if (key == 304) shift = !release; if (key == 306) control = !release; if (key == 308) alt = !release; if (shift) keyfact = -1; else keyfact = 1; if (release) return; int type = action->type[curr_act]; switch (key) { case SDLK_TAB: SetToolMode (1); break; case SDLK_ESCAPE: case SDLK_q: QuitTool (); break; case SDLK_F10: ScreenshotN (); break; case SDLK_s: SaveToolCharacter (); break; case SDLK_c: ScreenshotN (); break; case SDLK_m: TestChar.useMaterials = !TestChar.useMaterials; break; case SDLK_h: TestChar.useHighlighting = !TestChar.useHighlighting; break; case SDLK_r: TestChar.Reset (); ReloadToolCharacter (); ToolsInit (); break; case SDLK_u: if (action != NULL) { RecallAction (action); TestChar.RefreshNode (curr_node); } break; case SDLK_PLUS: case SDLK_EQUALS: // zoom in zposition += 0.1; xposition -= 0.03; break; case SDLK_MINUS: // zoom out zposition -= 0.1; xposition += 0.03; break; // set rotations for view case SDLK_1: SetRotation (0, 0, 0); break; case SDLK_2: SetRotation (-50, 180, 15); break; case SDLK_3: SetRotation (0, 180, 0); break; case SDLK_4: SetRotation (0, -80, 0); break; // select node case SDLK_PAGEUP: ChangeNode (-1); break; case SDLK_PAGEDOWN: ChangeNode (1); break; case SDLK_END: ChangeNode (charbase); break; case SDLK_HOME: ChangeNode (-charbase); break; // select action case SDLK_DOWN: if (curr_act < lastact) curr_act++; if (action->type[curr_act] == 4) comp = 0; else comp = 1; break; case SDLK_UP: if (curr_act > 0) curr_act--; if (action->type[curr_act] == 4) comp = 0; else comp = 1; break; case SDLK_LEFT: ChangeValue (type, -1); break; case SDLK_RIGHT: ChangeValue (type, 1); break; // select value case SDLK_SPACE: if (type == 0 || type == 4) { comp++; if (comp > 3) comp = 0; if (type == 0 && comp == 0) comp = 1; } break; default: break; } }