tsp.cpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "tsp.h"
4 #include <float.h>
5 
6 struct thread_data {
7  int tid;
8  TSP *tsp;
9 };
10 struct thread_data *data;
11 
12 void* F(void* args); // dsy
13 
14 //TSP::TSP(vector<Point_2> nodes){ // dsy
15 //
16 // // node num
17 // n = nodes.size();
18 //
19 // /* Allocate memory */
20 // graph = new double*[n];
21 // for (int i = 0; i < n; i++) {
22 // graph[i] = new double[n];
23 // for (int j = 0; j < n; j++) graph[i][j] = 0;
24 // }
25 //
26 // cost = new double*[n];
27 // for (int i = 0; i < n; i++) {
28 // cost[i] = new double[n];
29 // }
30 //
31 // path_vals = new double*[n];
32 // for (int i = 0; i < n; i++) {
33 // path_vals[i] = new double[n];
34 // }
35 //
36 // /* Adjacency lsit */
37 // adjlist = new vector<int>[n];
38 //
39 // /* set nodes */
40 // for (int i = 0; i < nodes.size(); i++)
41 // {
42 // struct City c = { nodes[i].x(), nodes[i].y() };
43 // cities.push_back(c);
44 // }
45 //
46 // /* set weights */
47 // { // threads to compute distance parallel
48 // int amount = (n / THREADS) * 0.2;
49 // int x = (n / THREADS) - amount; // min amount given to threads
50 // int rem = n - (x * THREADS);
51 // int half = THREADS / 2 + 1;
52 //
53 // int pos = 0;
54 // for (int i = 0; i < half; i++) {
55 // start_idx[i] = pos;
56 // pos += (x - 1);
57 // end_idx[i] = pos;
58 // pos++;
59 // }
60 // int remainingThreads = THREADS - half + 1;
61 // int extraToEach = rem / remainingThreads;
62 // // Divide remainer among second half of threads
63 // for (int i = half; i < THREADS; i++) {
64 // start_idx[i] = pos;
65 // pos += (x + extraToEach - 1);
66 // end_idx[i] = pos;
67 // pos++;
68 // }
69 // end_idx[THREADS - 1] = n - 1;
70 //
71 // int rc; void *status;
72 // data = new struct thread_data[n];
73 //
74 // // allocate space for n thread ids
75 // pthread_t *thread = new pthread_t[n];
76 // pthread_attr_t attr;
77 //
78 // // Initialize and set thread detached attribute
79 // pthread_attr_init(&attr);
80 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
81 //
82 // for (long t = 0; t < THREADS; t++) {
83 // //printf("Creating thread %ld\n", t);
84 // data[t].tid = t;
85 // data[t].tsp = this;
86 // rc = pthread_create(&thread[t], &attr, F, (void*)&data[t]);
87 // if (rc) {
88 // printf("ERROR; return code from pthread_create() is %d\n", rc);
89 // exit(-1);
90 // }
91 // }
92 //
93 // // Free attribute and wait for the other threads
94 // pthread_attr_destroy(&attr);
95 // for (long t = 0; t < THREADS; t++) {
96 // rc = pthread_join(thread[t], &status);
97 // if (rc) {
98 // printf("ERROR; return code from pthread_join() is %d\n", rc);
99 // exit(-1);
100 // }
101 // //printf("Completed join with thread %ld having a status of %ld\n",t,(long)status);
102 // }
103 // delete[] data;
104 // }
105 //
106 //}
107 
109 //TSP::TSP(vector<Point_2> nodes, vector<vector<double>> weights){ //dsy
110 //
111 // // node num
112 // n = nodes.size();
113 //
114 // /* Allocate memory */
115 // graph = new double*[n];
116 // for (int i = 0; i < n; i++) {
117 // graph[i] = new double[n];
118 // for (int j = 0; j < n; j++) graph[i][j] = 0;
119 // }
120 //
121 // cost = new double*[n];
122 // for (int i = 0; i < n; i++) {
123 // cost[i] = new double[n];
124 // }
125 //
126 // path_vals = new double*[n];
127 // for (int i = 0; i < n; i++) {
128 // path_vals[i] = new double[n];
129 // }
130 //
131 // /* Adjacency lsit */
132 // adjlist = new vector<int>[n];
133 //
134 // /* set nodes */
135 // for (int i = 0; i < nodes.size(); i++)
136 // {
137 // struct City c = { nodes[i].x(), nodes[i].y() };
138 // cities.push_back(c);
139 // }
140 //
141 // /* set weights */ // equal to: fill matrix process
142 // for (int i = 0; i < n; i++)
143 // for (int j = 0; j < n; j++)
144 // graph[i][j] = weights[i][j];
145 //
146 //}
147 
148 // constructor
149 TSP::TSP(vector<Eigen::Vector2d> nodes, vector<vector<double>> weights){ //dsy
150 
151  // node num
152  n = nodes.size();
153 
154  /* Allocate memory */
155  graph = new double*[n];
156  for (int i = 0; i < n; i++) {
157  graph[i] = new double[n];
158  for (int j = 0; j < n; j++) graph[i][j] = 0;
159  }
160 
161  cost = new double*[n];
162  for (int i = 0; i < n; i++) {
163  cost[i] = new double[n];
164  }
165 
166  path_vals = new double*[n];
167  for (int i = 0; i < n; i++) {
168  path_vals[i] = new double[n];
169  }
170 
171  /* Adjacency lsit */
172  adjlist = new vector<int>[n];
173 
174  /* set nodes */
175  for (int i = 0; i < nodes.size(); i++)
176  {
177  struct City c = { nodes[i].x(), nodes[i].y() };
178  cities.push_back(c);
179  }
180 
181  /* set weights */ // equal to: fill matrix process
182  for (int i = 0; i < n; i++)
183  for (int j = 0; j < n; j++)
184  graph[i][j] = weights[i][j];
185 
186 }
187 
188 TSP::TSP(string in, string out){
190  // Constructor
192  inFname = in; outFname = out;
193 
194  // set n to number of lines read from input file
195  getNodeCount();
196 
197  // Allocate memory
198  graph = new double*[n];
199  for (int i = 0; i < n; i++) {
200  graph[i] = new double[n];
201  for (int j = 0; j < n; j++) graph[i][j] = 0;
202  }
203 
204  cost = new double*[n];
205  for (int i = 0; i < n; i++) {
206  cost[i] = new double[n];
207  }
208 
209  path_vals = new double*[n];
210  for (int i = 0; i < n; i++) {
211  path_vals[i] = new double[n];
212  }
213 
214  // Adjacency lsit
215  adjlist = new vector<int> [n];
216 };
217 
220  // Destructor
222 
223  for (int i = 0; i < n; i++) {
224  delete [] graph[i];
225  delete [] cost[i];
226  delete [] path_vals[i];
227  }
228  delete [] path_vals;
229  delete [] graph;
230  delete [] cost;
231  delete [] adjlist;
232 }
233 
235  int count = 0;
236  ifstream inStream;
237  inStream.open(inFname.c_str(), ios::in);
238 
239  if (!inStream) {
240  cerr << "Can't open input file " << inFname << endl;
241  getchar(); getchar(); getchar(); // dsy
242  exit(1);
243  }
244  std::string unused;
245  while ( std::getline(inStream, unused) )
246  ++count;
247  n = count;
248  inStream.close();
249 };
250 
253  ifstream inStream;
254  inStream.open(inFname.c_str(), ios::in);
255  if (!inStream) {
256  cerr << "Can't open input file " << inFname << endl;
257  getchar(); getchar(); getchar(); // dsy
258  exit(1);
259  }
260  int c;
261  double x, y;
262  int i = 0;
263  while (!inStream.eof() ) {
264  inStream >> c >> x >> y;
265  // Push back new city to vector
266  struct City c = {x, y};
267  cities.push_back(c);
268  i++;
269  }
270  inStream.close();
271 };
272 
273 double TSP::get_distance(struct TSP::City c1, struct TSP::City c2) { // dsy modified
275  // Calculate distance between c1 and c2
277 
278  double result = 0;
279 
280  //cerr << "distance_";
281  //
283  //cv::Point beg((int)ceil(c1.x), -(int)ceil(c1.y));
284  //cv::Point end((int)ceil(c2.x), -(int)ceil(c2.y));
285  //cv::Mat background(row, col, CV_8UC1); // background
286  //for (int r = 0; r < row; r++)
287  //{
288  // for (int c = 0; c < col; c++)
289  // {
290  // if (cellmap[r][c].isScanned && cellmap[r][c].isOccupied)
291  // background.ptr<uchar>(r)[c] = 255;
292  // else
293  // background.ptr<uchar>(r)[c] = 0;
294  // }
295  //}
296  //if (occlusionCheck(background, beg, end)) // obsticle
297  //{
298  // vector<Point_2> path;
299  // Point_2 p0(c1.x, c1.y);
300  // Point_2 p1(c2.x, c2.y);
301  // result = get_geodesic_distance(p0, p1, path);
302  // cerr << "geodesic = " << result << endl;
303  //}
304  //else // no obsticle
305  //{
306  // Point_2 p1(c1.x, c1.y);
307  // Point_2 p2(c2.x, c2.y);
308  // result = get_euclidean_distance(p1, p2);
309  // // test
310  // double dx = (double)(c1.x - c2.x);
311  // double dy = (double)(c1.y - c2.y);
312  // cerr << "euclidean = " << result << " = " << sqrt(dx*dx + dy*dy) << endl;;
313  //}
314  //
316 
317  return result;
318 };
319 
320 void* F(void* args){
321  struct thread_data *my_data = (struct thread_data *) args;
322  int tid = my_data->tid;
323  TSP *tsp = my_data->tsp;
324  double **graph = tsp->graph;
325  int start, end;
326 
327  start = tsp->start_idx[tid];
328  end = tsp->end_idx[tid];
329 
330  //clock_t t = clock();
331  // fill matrix with distances from every city to every other city
332  for (int i = start; i <= end; i++) {
333  for (int j = i; j < tsp->n; j++) {
334  // Don't delete this line it's supposed to be there.
335  graph[i][j] = graph[j][i] = tsp->get_distance(tsp->cities[i], tsp->cities[j]);
336  }
337  }
338  //t = clock() - t;
339  //t = clock();
340  //cout << "thread " << tid << " time: " << 1000*(((float)clock())/CLOCKS_PER_SEC) << " s"<< endl;
341  pthread_exit(NULL);
342 
343  return 0;
344 }
345 
349  int amount = (n / THREADS) * 0.2;
350  int x = (n / THREADS) - amount; // min amount given to threads
351  int rem = n - (x * THREADS);
352  int half = THREADS/2 + 1;
353 
354  int pos = 0;
355  for (int i = 0; i < half; i++) {
356  start_idx[i] = pos;
357  pos += (x - 1);
358  end_idx[i] = pos;
359  pos++;
360  }
361  int remainingThreads = THREADS - half + 1;
362  int extraToEach = rem / remainingThreads;
363  // Divide remainer among second half of threads
364  for (int i = half; i < THREADS; i++) {
365  start_idx[i] = pos;
366  pos += (x + extraToEach - 1);
367  end_idx[i] = pos;
368  pos++;
369  }
370  end_idx[THREADS-1] = n - 1;
371 
372  int rc; void *status;
373  data = new struct thread_data[n];
374 
375  // allocate space for n thread ids
376  pthread_t *thread = new pthread_t[n];
377  pthread_attr_t attr;
378 
379  // Initialize and set thread detached attribute
380  pthread_attr_init(&attr);
381  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
382 
383  for (long t = 0; t < THREADS; t++) {
384  //printf("Creating thread %ld\n", t);
385  data[t].tid = t;
386  data[t].tsp = this;
387  rc = pthread_create(&thread[t], &attr, F, (void*)&data[t]);
388  if (rc) {
389  printf("ERROR; return code from pthread_create() is %d\n", rc);
390  getchar(); getchar(); getchar(); // dsy
391  exit(-1);
392  }
393  }
394 
395  // Free attribute and wait for the other threads
396  pthread_attr_destroy(&attr);
397  for (long t = 0; t < THREADS; t++) {
398  rc = pthread_join(thread[t], &status);
399  if (rc) {
400  printf("ERROR; return code from pthread_join() is %d\n", rc);
401  getchar(); getchar(); getchar(); // dsy
402  exit(-1);
403  }
404  //printf("Completed join with thread %ld having a status of %ld\n",t,(long)status);
405  }
406  delete [] data;
407 }
408 
411  // In each iteration, we choose a minimum-weight
412  // edge (u, v), connecting a vertex v in the set A to
413  // the vertex u outside of set A
415  double* key = new double[n]; // Key values used to pick minimum weight edge in cut
416  bool* in_mst = new bool[n]; // To represent set of vertices not yet included in MST
417  int* parent = new int[n];
418 
419  // For each vertex v in V
420  for (int v = 0; v < n; v++) {
421  // Initialize all keys to infinity
422  //key[v] = std::numeric_limits<double>::max();
423  key[v] = DBL_MAX;
424 
425  // Mark as not being in mst yet
426  in_mst[v] = false;
427  }
428 
429  // Node 0 is the root node so give it the lowest distance (key)
430  key[0] = 0;
431  parent[0] = -1; // First node is always root of MST
432 
433  for (int i = 0; i < n - 1; i++) {
434  // Find closest remaining (not in tree) vertex
435  // TO DO : This would be better represented by heap/pqueue
436  int v = minKey(key, in_mst);
437 
438  // Add vertex v to the MST
439  in_mst[v] = true;
440 
441  // Look at each vertex u adjacent to v that's not yet in mst
442  for (int u = 0; u < n; u++) {
443  if (graph[v][u] && in_mst[u] == false && graph[v][u] < key[u]) {
444  // Update parent index of u
445  parent[u] = v;
446 
447  // Update the key only if dist is smaller than key[u]
448  key[u] = graph[v][u];
449  }
450  }
451  }
452 
453  // map relations from parent array onto matrix
454  for (int v1 = 0; v1 < n; v1++) {
455  // there is an edge between v1 and parent[v1]
456  int v2 = parent[v1];
457  if (v2 != -1) {
458  adjlist[v1].push_back(v2);
459  adjlist[v2].push_back(v1);
460  }
461  }
462 
463  delete[] key;
464  delete[] in_mst;
465  delete[] parent;
466 };
467 
468 // findMST helper function
469 int TSP::minKey(double key[], bool mstSet[]) {
470  // Initialize min value
471  //double min = std::numeric_limits<double>::max();
472  double min = DBL_MAX;
473  int min_index;
474  for (int v = 0; v < n; v++)
475  if (mstSet[v] == false && key[v] < min) {
476  min = key[v];
477  min_index = v;
478  }
479  return min_index;
480 };
481 
484  // Find nodes with odd degrees in T to get subgraph O
486 
487  // store odds in new vector for now
488  for (int r = 0; r < n; r++) {
489  //cities[r].isOdd = ((adjlist[r].size() % 2) == 0) ? 0 : 1;
490  if ((adjlist[r].size() % 2) != 0 ) {
491  odds.push_back(r);
492  }
493  }
494 }
495 
498  // find a perfect matching M in the subgraph O using greedy algorithm
499  // but not minimum
501  int closest;
502  double length;
503  std::vector<int>::iterator tmp, first;
504 
505  // Find nodes with odd degrees in T to get subgraph O
506  findOdds();
507 
508  // for each odd node
509  while (!odds.empty()) {
510  first = odds.begin();
511  vector<int>::iterator it = odds.begin() + 1;
512  vector<int>::iterator end = odds.end();
513  //length = std::numeric_limits<double>::max();
514  length = DBL_MAX;
515  for (; it != end; ++it) {
516  // if this node is closer than the current closest, update closest and length
517  if (graph[*first][*it] < length) {
518  length = graph[*first][*it];
519  closest = *it;
520  tmp = it;
521  }
522  } // two nodes are matched, end of list reached
523  adjlist[*first].push_back(closest);
524  adjlist[closest].push_back(*first);
525  odds.erase(tmp);
526  odds.erase(first);
527  }
528 }
529 
530 
531 // Take reference to a path vector
532 // so can either modify actual euler path or a copy of it
533 void TSP::euler (int pos, vector<int> &path) {
535  // Based on this algorithm:
536  // http://www.graph-magics.com/articles/euler.php
537  // we know graph has 0 odd vertices, so start at any vertex
538  // O(V+E) complexity
540 
541  // make copy of original adjlist to use/modify
542  vector<int> *temp = new vector<int> [n];
543  for (int i = 0; i < n; i++) {
544  temp[i].resize(adjlist[i].size());
545  temp[i] = adjlist[i];
546  }
547 
548  path.clear();
549 
550  // Repeat until the current vertex has no more neighbors and the stack is empty.
551  stack<int> stk;
552  while (!stk.empty() || temp[pos].size() > 0 ) {
553  // If current vertex has no neighbors -
554  if (temp[pos].size() == 0) {
555  // add it to circuit,
556  path.push_back(pos);
557  // remove the last vertex from the stack and set it as the current one.
558  int last = stk.top();
559  stk.pop();
560  pos = last;
561  }
562  // Otherwise (in case it has neighbors)
563  else {
564  // add the vertex to the stack,
565  stk.push(pos);
566  // take any of its neighbors,
567  int neighbor = temp[pos].back();
568  // remove the edge between selected neighbor and that vertex,
569  temp[pos].pop_back();
570  for (unsigned int i = 0; i < temp[neighbor].size(); i++)
571  if (temp[neighbor][i] == pos) { // find position of neighbor in list
572  temp[neighbor].erase (temp[neighbor].begin() + i); // remove it
573  break;
574  }
575  // and set that neighbor as the current vertex.
576  pos = neighbor;
577  }
578  }
579  path.push_back(pos);
580 }
581 
582 
583 void TSP::make_hamilton(vector<int> &path, double &path_dist) {
584  // remove visited nodes from Euler tour
585  bool* visited = new bool[n]; // boolean value for each node if it has been visited yet
586  memset(visited, 0, n * sizeof(bool));
587 
588  path_dist = 0;
589 
590  int root = path.front();
591  vector<int>::iterator curr = path.begin();
592  vector<int>::iterator next = path.begin()+1;
593  visited[root] = true;
594 
595  // loop until the end of the circuit list is reached
596  while ( next != path.end() ) {
597  // if we haven't been to the next city yet, go there
598  if (!visited[*next]) {
599  path_dist += graph[*curr][*next];
600  curr = next;
601  visited[*curr] = true;
602  next = curr + 1;
603  }else {
604  next = path.erase(next); // remove it
605  }
606  }
607 
608  // add the distance back to the root
609  path_dist += graph[*curr][*next];
610 
611  delete[] visited;
612 }
613 
614 
615 
616 
617 
618 void TSP::create_tour(int pos){
619  // call euler with actual circuit vector
620  euler(pos, circuit);
621 
622  // make it hamiltonian
623  // pass actual vars
624  make_hamilton(circuit, pathLength);
625 }
626 
627 
628 // Does euler and hamilton but doesn't modify any variables
629 // Just finds path length from the node specified and returns it
630 int TSP::find_best_path (int pos) {
631 
632  // create new vector to pass to euler function
633  vector<int>path;
634  euler(pos, path);
635 
636  // make it hamiltonian, pass copy of vars
637  double length;
638  make_hamilton(path, length);
639 
640  // Optimize
641  twoOpt(graph, path, length, n);
642  twoOpt(graph, path, length, n);
643  twoOpt(graph, path, length, n);
644  twoOpt(graph, path, length, n);
645  twoOpt(graph, path, length, n);
646 
647  return length;
648 }
649 
650 
652  // Modify circuit & pathLength
653  twoOpt(graph, circuit, pathLength, n);
654 }
655 
656 
657 
658 
659 //================================ PRINT FUNCTIONS ================================//
660 
662  ofstream outputStream;
663  outputStream.open(outFname.c_str(), ios::out);
664  outputStream << pathLength << endl;
665  for (vector<int>::iterator it = circuit.begin(); it != circuit.end(); ++it) {
666  //for (vector<int>::iterator it = circuit.begin(); it != circuit.end()-1; ++it) {
667  outputStream << *it << endl;
668  }
669  //outputStream << *(circuit.end()-1);
670  outputStream.close();
671 
672  // dsy test
673  ofstream ofs("data/OfflineOutput/tsp.m");
674  for (vector<int>::iterator it = circuit.begin(); it != circuit.end(); ++it) {
675  ofs << "plot([" << cities[*it].x << ", " << cities[*it + 1].x << "], [" << cities[*it].y << ", " << cities[*it + 1].y << "]); hold on;" << endl;
676  ofs << "text(" << cities[*it].x << ", " << cities[*it].y << ", '" << *it << "'); hold on;" << endl;
677  }
678  ofs.close();
679 };
680 
682  cout << endl;
683  for (vector<int>::iterator it = circuit.begin(); it != circuit.end()-1; ++it) {
684  cout << *it << " to " << *(it+1) << " ";
685  cout << graph[*it][*(it+1)] << endl;
686  }
687  cout << *(circuit.end()-1) << " to " << circuit.front();
688 
689  cout << "\nLength: " << pathLength << endl << endl;
690 };
691 
693  for (vector<int>::iterator it = circuit.begin(); it != circuit.end(); ++it)
694  cout << *it << endl;
695 }
696 
698  for (int i = 0; i < n; i++) {
699  cout << i << ": "; //print which vertex's edge list follows
700  for (int j = 0; j < (int)adjlist[i].size(); j++) {
701  cout << adjlist[i][j] << " "; //print each item in edge list
702  }
703  cout << endl;
704  }
705 };
706 
708  cout << endl;
709  int i = 0;
710  for (vector<City>::iterator it = cities.begin(); it != cities.end(); ++it)
711  cout << i++ << ": " << it->x << " " << it->y << endl;
712 }
713 
714 
void findOdds()
Definition: tsp.cpp:482
#define min(a, b)
Definition: Chen_Han.cpp:11
#define THREADS
Definition: tsp.h:44
double twoOpt(double **graph, vector< int > &path, double &pathLength, int n)
Definition: twoOpt.cpp:40
double get_distance(struct City c1, struct City c2)
Definition: tsp.cpp:273
int start_idx[THREADS]
Definition: tsp.h:113
int find_best_path(int)
Definition: tsp.cpp:630
ROSCPP_DECL void start()
void printCities()
Definition: tsp.cpp:707
int n
Definition: tsp.h:93
int minKey(double key[], bool mstSet[])
Definition: tsp.cpp:469
void readCities()
Definition: tsp.cpp:251
void fillMatrix_threads()
Definition: tsp.cpp:346
TSP(string in, string out)
Definition: tsp.cpp:188
double x
Definition: tsp.h:61
void printAdjList()
Definition: tsp.cpp:697
int end_idx[THREADS]
Definition: tsp.h:115
void make_hamilton(vector< int > &, double &)
Definition: tsp.cpp:583
void perfect_matching()
Definition: tsp.cpp:496
void findMST_old()
Definition: tsp.cpp:409
void make_shorter()
Definition: tsp.cpp:651
Definition: tsp.h:54
double ** graph
Definition: tsp.h:102
void printEuler()
Definition: tsp.cpp:692
void euler(int pos, vector< int > &)
Definition: tsp.cpp:533
int tid
Definition: tsp.cpp:7
void create_tour(int)
Definition: tsp.cpp:618
TSP * tsp
Definition: tsp.cpp:8
void getNodeCount()
Definition: tsp.cpp:234
void * F(void *args)
Definition: tsp.cpp:320
void printResult()
Definition: tsp.cpp:661
vector< City > cities
Definition: tsp.h:99
Definition: tsp.h:59
void printPath()
Definition: tsp.cpp:681
~TSP()
Definition: tsp.cpp:218
struct thread_data * data
Definition: tsp.cpp:10


co_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:00:56