This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
csce420pine64backup/hw1/hw1pr2.cpp
2017-10-24 08:49:03 -05:00

225 lines
4.1 KiB
C++

// Alexander Huddleston
// 10/2/17
// hw1pr2.cpp
// Read a file of points, compute interative best-first of a closed path between points.
#include<stdio.h>
#include<iostream>
#include<fstream>
#include<cmath>
#include<future>
#include<chrono>
#include<vector>
#include<climits>
#include<unordered_set>
using namespace std;
// Double vector used to store list of squared distances between points.
vector<vector<long int>> dmat;
vector<tuple<int, int>> points;
unordered_set<long int> relaxed_edges;
void store_points(ifstream *input, string filename)
{
input->open(filename);
string line = "";
string token = "";
tuple<int, int> 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<long int> 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<int> 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<long double> 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<int, int> tempx;
tuple<int, int> 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;
}