1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#include <iostream>
#include <fstream>
#include <math.h>
using std::cout;
using std::ifstream;
#define NUMPOINTS 100 //a maximum
#define DIMENTIONS 3 //this isn't really flexible since the file format is hard coded. oh well.
#define MAXCONNECTIONS 12
#define DATAFILE "connections.txt"
//Format:
//pointID, point x, point y, point z, number of connections, (connected id 1, connected id 2, ...), -1
//the -1 is a terminator that lets me find my typos. I hope. Since I'm not coding any other sanity checking.
//the first point is the origin
//the last point is the destination
//-----The main data set is globally available-------
float points[NUMPOINTS][DIMENTIONS];//3 dimensions worth of coordinates
float totaldistance[NUMPOINTS]; //total distance from start
bool visited[NUMPOINTS]; // if set, point does not need calculating again
int connectedpoints[NUMPOINTS][MAXCONNECTIONS]; //list of connected points, possibly complete.
int arrivedfrom[NUMPOINTS]; //set when a point's total distance is altered. indicates what node was being visited when
//----------------------------------------------------
float getdistance(int p1, int p2);
int closestpoint();
void calcneighbors(int p1); //update distances to all unvisited neighbors
int main () {
int p1=0, p2=0, pmax=0, c=0, nc=0, z=0, error=0;
int firstpoint=0, lastpoint=0, steps=0;
float x=0, y=0, d=0;
//clean the arrays
for (p1=0; p1<NUMPOINTS; p1++) {
visited[p1]=0;
arrivedfrom[p1]=0;
totaldistance[p1]=0;
for (c=0; c<DIMENTIONS; c++) {
points[p1][c]=0;
}
for (c=0; c<MAXCONNECTIONS; c++) {
connectedpoints[p1][c]=0;
}
}
p1=0; c=0; //reinitialize after flush
//read file of points and connections
ifstream file(DATAFILE);
while(!file.eof() && (error==0)) {
file >> p1;
if (firstpoint==0) {
firstpoint=p1; //remember the first point read
}
lastpoint=p1; //remember the last point read
file >> points[p1][0] >> points[p1][1] >> points[p1][2];
file >> nc;
for (c=0; c<nc; c++) {
file >> connectedpoints[p1][c];
}
file >> z;
if (z != -1) {
cout <<"\n\n HUGE ERROR! p1=" << p1 << " nc=" << nc <<" !!!\n\n";
error=1;
}
}
file.close();
//DEBUG:
cout << "First point ID " << firstpoint << "\n" ;
cout << "Last point ID " << lastpoint << "\n" ;
cout << "Distance as bird flies: " << getdistance(firstpoint,lastpoint) << "\n";
cout << "Closest unvisited point: " << closestpoint() << "\n";
//END DEBUG
//BEGIN JOURNEY
p1=firstpoint;
calcneighbors(p1);
while (p1!=lastpoint) {
visited[p1]=1; //mark current point
p2=closestpoint();
cout << "Visited " << p1 << ". Closest unvisited point: " << p2 << " trip distance of " << totaldistance[p2] << "\n"; //DEBUG
p1=p2; //go to that point
calcneighbors(p1);
steps++;
}
cout << "Total distance of " << totaldistance[lastpoint] << " with " << steps << " steps.\n";
//SHOW ME THE WAY HOME (the solution)
p1=lastpoint;
cout << "Path back: ";
while (p1 != firstpoint) {
cout << p1 << " - ";
p1=arrivedfrom[p1];
}
cout << p1 << ".\n";
}
//
//return distance between two points
//
float getdistance(int p1, int p2) {
float squared=0;
int d=0;
for (d=0; d<DIMENTIONS; d++) {
squared+=(points[p1][d]-points[p2][d])*(points[p1][d]-points[p2][d]);
}
return sqrt(squared);
}
//
//return closest unvisited point
//
int closestpoint() {
int p1=0, point=0;
float d=0;
for (p1=0; p1 < NUMPOINTS ; p1++) {
if (visited[p1]==0 && totaldistance[p1]!=0) { //ignore uncalculated
if (totaldistance[p1] < d || d==0) { //first found or smaller distance
d=totaldistance[p1];
point=p1;
}
}
}
return point;
}
//
// Update distances to connected and unvisited points
//
void calcneighbors (int p1) {
int p2=0, c=0;
float d=0;
while (connectedpoints[p1][c]!=0) {
p2=connectedpoints[p1][c];
if (visited[p2]==0) {
d=getdistance (p1,p2);
cout << p1 << " " << p2 << " " << d << " calculated\n"; //DEBUG
if (d < totaldistance[p2] || totaldistance[p2]==0) { //if less than or if first time
totaldistance[p2] = d; //update distance
arrivedfrom[p2] = p1; //leave a hans-n-gretel breadcrumb
cout << p1 << " " << p2 << " " << d << " updated\n"; //DEBUG
}
}
c++;
}
}
|