// 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);
}
예제 #2
0
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;
	}
}