// Alexander Huddleston // 10/2/17 // hw1pr2.cpp // Read a file of points, compute interative best-first of a closed path between points. #include #include #include #include #include #include #include #include #include using namespace std; // Double vector used to store list of squared distances between points. vector> dmat; vector> points; unordered_set relaxed_edges; void store_points(ifstream *input, string filename) { input->open(filename); string line = ""; string token = ""; tuple temp_point; get<0>(temp_point) = 0.0; get<1>(temp_point) = 0.0; while(getline(*input, line)) { for(char c : line) { if(c == ' ') { get<0>(temp_point) = stof(token); token = ""; } else { token = token + c; } } get<1>(temp_point) = stof(token); token = ""; points.push_back(temp_point); } input->close(); } void store_distances() { long int d1 = 0.0; long int d2 = 0.0; tuple< int, int> x; tuple< int, int> y; get<0>(x) = 0.0; get<1>(x) = 0.0; get<0>(y) = 0.0; get<1>(y) = 0.0; vector tempvec; for(int r = points.size() - 1; r >= 0; --r) { for(int c = 0; c < points.size() - (points.size() - r); ++c) { x = points.at(r); y = points.at(c); d1 = (get<0>(x) - get<0>(y)); d2 = (get<1>(x) - get<1>(y)); tempvec.push_back(d1*d1 + d2*d2); } dmat.push_back(tempvec); tempvec.clear(); } } bool is_visited(vector relaxed_edges, int index) { for(int x : relaxed_edges) { if(x == index) { return true; } } return false; } long double best_first(ifstream *input, string filename) { // First, store the points from the file into global vector. store_points(input, filename); // Small optomization so we don't have to call points.size() so much. long int n = points.size(); // Store squared distances into dmat. // Ignore duplicate distances, 0 vectors. store_distances(); // Find best-first shortest path. // Keep edges we've already visited. // Store distance up to this point. long double current_distance = 0; // Using this to keep track of selected node. long int current_node = 0; long int selected_node = 0; // Using this to keep track of min distance. long int min_distance = 0; while(relaxed_edges.size() < (n - 1)) { min_distance = INT_MAX; for(int i = 0; i < (n - 1); ++i) { while(relaxed_edges.find(i) != relaxed_edges.end()) { ++i; if(i == current_node) { ++i; } } if(i > (n - 1)) { break; } if(i < current_node) { if(min_distance > dmat.at(i).at((n - 1) - current_node)) { selected_node = ((n - 1) - i); min_distance = dmat.at(i).at((n - 1) - current_node); } } else { if(i == current_node) { ++i; if(i > (n - 1)) { break; } } if(min_distance > dmat.at(current_node).at((n - 1) - i)) { selected_node = ((n - 1) - i); min_distance = dmat.at(current_node).at((n - 1) - i); } } } relaxed_edges.insert((n - 1) - current_node); current_node = selected_node; current_distance += sqrt(min_distance); } current_distance += sqrt(dmat.at(current_node).at(0)); return current_distance; } int main() { ifstream input; string filename = "hw1pr_data.txt"; future fut = async(best_first, &input, filename); chrono::milliseconds span(60000); while((fut.wait_for(span)==future_status::timeout) || input.is_open()) { } if(input.is_open()) { input.close(); } long double total = fut.get(); tuple tempx; tuple tempy; long int temp; for(long int i : relaxed_edges) { tempx = points.at(temp); tempy = points.at(i); cout << get<0>(tempx) << "\t" << get<1>(tempx) << "\t" << get<0>(tempy) << "\t" << get<1>(tempy) << endl; temp = i; } cout << total << endl; return 0; }