⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit_main.cpp

📁 针对TSP问题
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
  Version History
  ver 1.00 Dec  9, 1997 Official Release
  ver 1.01 Dec 10, 1997 Add a write button

  Flags:

  TForm1->AS_start : if a valid instance ready
  cities->loaded   : if a TSP file loaded (Global Var: AS)
*/
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "Unit_Main.h"
//---------------------------------------------------------------------------
#pragma link "titlebar"
#pragma link "Digits"
#pragma resource "*.dfm"
TASForm *ASForm;
//---------------------------------------------------------------------------
cities::cities(int nc, int na, double pa, double pb, double pe, double pq, double pt) {
  nofc = nc;
  nofa = na;
  alpha = pa;
  beta = pb;
  evaporation = pe;
  Q = pq;
  tolerance = pt;
  best_length = MAXDOUBLE;
  cycle_count_when_best_found = 0;

  tao = new double * [nofc];
  visibility = new double * [nofc];
  city = new double * [nofc];
  ants = new int *[nofa];
  allowed = new int * [nofa];
  lengths = new double [nofa],
  prob = new double[nofc];
  best_solution = new int[nofc];
  for(int i = 0; i < nofc; i++) {
    tao[i] = new double[nofc];
    visibility[i] = new double[nofc];
    city[i] = new double[2];
  }

  for(int i = 0; i < nofa; i++) {
    ants[i] = new int[nofc];
    allowed[i] = new int[nofc];
  }

}

cities::~cities() {
  for(int i = 0; i < nofc; i++) {
    delete tao[i];
    delete visibility[i];
    delete city[i];
  }

  for(int i = 0; i < nofa; i++) {
    delete ants[i];
    delete allowed[i];
  }
  delete tao, visibility, city, ants, allowed, lengths, prob, best_solution;
}

void cities::change_p(double pa, double pb, double pe, double pq, double pt) {
  alpha = pa;
  beta = pb;
  evaporation = pe;
  Q = pq;
  tolerance = pt;
}

void cities::generate_city_map() {
  // add a CheckBox to randomize
  if (ASForm->CheckBox_random->Checked) {
    unsigned int tt = GetTickCount();
    char line[80];
    itoa(tt, line, 10);
    ASForm->Edit_seed->Text = line;
    srand(tt);
  } else
    srand(ASForm->Edit_seed->Text.ToInt());

  for(int i = 0; i < nofc; i++) {
    city[i][0] = (rand() % 10000) / 10000.0;
    city[i][1] = (rand() % 10000) / 10000.0;
  }
}

void cities::load_city_map(AnsiString pf, AnsiString tf) {
  loaded = true;
  file_loaded = pf;

  // open the city points file
  char line[81];
  FILE * f = fopen(pf.c_str(), "rt");
  // skip the number of cities
  fgets(line, 80, f);
  double x1, y1;
  for(int i = 0; i < nofc; i++) {
    fgets(line, 80, f);
    sscanf(line, "%lf %lf", &x1, &y1);
    city[i][0] = x1;
    city[i][1] = y1;
  }
  fclose(f);

  // get the optimal solution
  optimal_solution = new int[nofc];
  f = fopen(tf.c_str(), "rt");
  for(int i = 0; i < nofc; i++) {
    fgets(line, 80, f);
    sscanf(line, "%d", &optimal_solution[i]);
    optimal_solution[i]--; // start with city(1) rather than (0)
  }
  fclose(f);

  // calculate the optimal length
  optimal_length = 0;
  for(int i = 0; i < nofc - 1; i++) {
    optimal_length +=
      sqrt(
      (city[ optimal_solution[i] ][0] - city[ optimal_solution[i+1] ][0]) *
      (city[ optimal_solution[i] ][0] - city[ optimal_solution[i+1] ][0]) +
	  (city[ optimal_solution[i] ][1] - city[ optimal_solution[i+1] ][1]) *
	  (city[ optimal_solution[i] ][1] - city[ optimal_solution[i+1] ][1])
      );
  }
  optimal_length +=
    sqrt(
    (city[ optimal_solution[nofc-1] ][0] - city[ optimal_solution[0] ][0]) *
    (city[ optimal_solution[nofc-1] ][0] - city[ optimal_solution[0] ][0]) +
	(city[ optimal_solution[nofc-1] ][1] - city[ optimal_solution[0] ][1]) *
	(city[ optimal_solution[nofc-1] ][1] - city[ optimal_solution[0] ][1])
    );
}

void cities::ini_visibility_and_tao() {
  for(int i = 0; i < nofc; i++) {
    for(int j = 0; j < nofc; j++) {
	  // a little bit waste of time
	  if (i != j) {
        visibility[i][j] = (city[i][0] - city[j][0])*(city[i][0] - city[j][0]) +
                           (city[i][1] - city[j][1])*(city[i][1] - city[j][1]);
        visibility[i][j] = 1 / sqrt(visibility[i][j]);
      } else
        visibility[i][j] = 0;

      tao[i][j] = 1.0;
    }
  }
}

bool cities::one_cycle() {
  // put every city in each ant's alloed list
  for(int i = 0; i < nofa; i++)
    for (int j = 0; j < nofc; j++)
      allowed[i][j] = j;

  // assign the starting town to ants randomly
  // and eliminate this town from allowed[][]
  // add a CheckBox to select different ini configuratiion
  // int temp;
  for(int i = 0; i < nofa; i++) {
    ants[i][0] = i % nofc;
    // temp = allowed[i][ [ants[i][0] ];
    allowed[i][ ants[i][0] ] = allowed[i][nofc - 1];
    // allowed[i][nofc - 1] = temp;
  }
  // remember to re-initialize the random generator
  srand(GetTickCount());

  int tc = 0, 	// time & position counter (unnecessary, use x)
      which_t;	// which town is the next?

  double dice, sum_p;
  // main cycle
  for(int x = 0; x < nofc - 1; x++) {
    for(int i = 0; i < nofa; i++) {
      // decide which town should ant(i) go
      // (1) calculate the summation of all probabilities
      sum_p = 0;
      for(int j = 0; j < nofc - tc - 1; j++) {
        prob[j] = pow( tao[ ants[i][tc] ][ allowed[i][j] ], alpha) *
                  pow( visibility[ ants[i][tc] ][ allowed[i][j] ], beta);
        sum_p += prob[j];
      }

      // (2) roll a dice and decide which town to go
      dice = ((double)rand() / RAND_MAX) * sum_p;
      for(int j = 0; j <nofc -tc - 1; j++) {
        dice -= prob[j];
        if (dice < 0) {
          which_t = j;
          break;
        }
      }

      // (3) put the next town in ant(i)'s tabu list
      //     and eliminate this town from the ant's allowed list
      ants[i][tc + 1] = allowed[i][which_t];
      // temp = allowed[i][which_t];
      allowed[i][which_t] = allowed[i][nofc - tc - 2];
      // allowed[i][nofc - tc - 2] = temp;
    } // end of each ant in a time unit
    tc++;
  } // end of one cycle

  // compute the length found by each ant
  double min_length = MAXDOUBLE;
  best_ant = 0;
  for(int i = 0; i < nofa; i++) {
    lengths[i] = 0;
    for(int j = 0; j < nofc - 1; j++)
      // the inverse computation can be eliminated
      lengths[i] += 1 / visibility[ ants[i][j] ][ ants[i][j+1] ];
    lengths[i] += 1 / visibility[ ants[i][nofc-1] ][ ants[i][0] ];
    if (min_length > lengths[i]) {
      best_ant = i;
      min_length = lengths[i];
    }
  }

  // update the tao, note to remian the symmetry
  for(int i = 0; i < nofc; i++)
    for(int j = 0; j < nofc; j++)
      tao[i][j] *= evaporation;

  for(int i = 0; i < nofa; i++) {
    for(int j = 0; j < nofc - 1; j++) {
      tao[ ants[i][j] ][ ants[i][j+1] ] += Q / lengths[i];
      tao[ ants[i][j+1] ][ ants[i][j] ] += Q / lengths[i];
    }
    tao[ ants[i][nofc - 1] ][ ants[i][0] ] += Q / lengths[i];
    tao[ ants[i][0] ][ ants[i][nofc - 1] ] += Q / lengths[i];
  }

  // check for stagnation
  bool stagnation = true;
  for(int i = 0; i < nofa - 1; i++) {
    if (fabs(lengths[i] - lengths[i + 1]) > tolerance) {
      stagnation = false;
      break;
    }
  }
  if (nofa == 1)
    stagnation = false;

  // update the best solution
  if (lengths[best_ant] < best_length) {
    cycle_count_when_best_found = ASForm->step_count;
    best_length = lengths[best_ant];
    for(int i = 0; i < nofc; i++)
      best_solution[i] = ants[best_ant][i];
  }

  return stagnation;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -