Commit 79ed2636 authored by Colby Green's avatar Colby Green
Browse files

changes

parent 74d73c41
// Project Identifier: 5949F553E20B650AB0FB2266D3C0822B13D248B0
#ifndef lol
#define lol
#include <vector>
#include <cmath>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <limits>
using namespace std;
struct Poke {
Poke(int xcord_in, int ycord_in)
: xcord(xcord_in), ycord(ycord_in){}
int xcord;
int ycord;
};
class FASTTSP {
public:
void solve(){
// step 1
// start of tsp will always be the 0th pokemon
tspPokeDex.push_back(0);
tspPokeDex.push_back(1);
tspPokeDex.push_back(2);
totalDistance = pokeDistance(pokeDex[0], pokeDex[1]) + pokeDistance(pokeDex[1], pokeDex[2]) + pokeDistance(pokeDex[2], pokeDex[0]);
size_t curPokemonIndex = 3;
while (tspPokeDex.size() != pokeDex.size()){
// step 3
// step 4
double minDistance = numeric_limits<double>::infinity();
size_t curInsertionIndex = 0;
for (size_t i = 0; i < tspPokeDex.size(); i++){
size_t index = tspPokeDex[i];
size_t indexAfter = tspPokeDex[(i + 1) % tspPokeDex.size()];
double distance = pokeDistance(pokeDex[index], pokeDex[curPokemonIndex]) + pokeDistance(pokeDex[curPokemonIndex], pokeDex[indexAfter]) - pokeDistance(pokeDex[index], pokeDex[indexAfter]);
if (distance < minDistance){
minDistance = distance;
curInsertionIndex = i;
}
}
tspPokeDex.insert(tspPokeDex.begin() + int(curInsertionIndex) + 1, curPokemonIndex);
totalDistance += minDistance;
curPokemonIndex++;
}
}
FASTTSP(){
totalDistance = 0;
}
vector<size_t> getTspPokeDex(){
return tspPokeDex;
}
vector<Poke> getPokeDex(){
return pokeDex;
}
void readFile(){
cin >> numPokemon;
int xcord, ycord;
while (cin >> xcord && cin >> ycord){
Poke pokemon(xcord, ycord);
pokeDex.push_back(pokemon);
}
}
void print(){
cout << totalDistance << "\n";
for (size_t i = 0; i < tspPokeDex.size(); i++){
cout << tspPokeDex[i] << " ";
}
}
private:
vector<Poke> pokeDex;
vector<size_t> tspPokeDex;
double totalDistance;
size_t numPokemon;
double pokeDistance(Poke &poke1, Poke &poke2){
double x = poke1.xcord - poke2.xcord;
double y = poke1.ycord - poke2.ycord;
double dist = (x * x) + (y * y);
dist = sqrt(dist);
return dist;
}
};
#endif
......@@ -7,84 +7,71 @@
#include <string>
#include <limits>
using namespace std;
struct Pokemon {
Pokemon(){}
Pokemon(int xcord, int ycord){
this->xcord = xcord;
this->ycord = ycord;
minDistanceTo = numeric_limits<double>::infinity();
precedingPokemonIndex = -1;
if ((xcord == 0 && ycord <= 0) || (xcord <= 0 && ycord == 0)){
terrain = 'c';
}else if (xcord <= 0 && ycord <= 0){
terrain = 'w';
}else {
terrain = 'l';
}
}
char terrain;
double minDistanceTo;
int precedingPokemonIndex;
int xcord;
int ycord;
};
double pokeDistance(Pokemon &poke1, Pokemon &poke2){
if ((poke1.terrain == 'l' && poke2.terrain == 'w') || (poke1.terrain == 'w' && poke2.terrain == 'l')){
return numeric_limits<double>::infinity();
}else {
double x = poke1.xcord - poke2.xcord;
double y = poke1.ycord - poke2.ycord;
double dist = (x * x) + (y * y);
dist = sqrt(dist);
return dist;
}
}
class Mst {
public:
struct Pokemon {
Pokemon(){}
Pokemon(int xcord, int ycord){
this->xcord = xcord;
this->ycord = ycord;
minDistanceTo = numeric_limits<double>::infinity();
precedingPokemonIndex = -1;
visited = false;
if ((xcord == 0 && ycord <= 0) || (xcord <= 0 && ycord == 0)){
terrain = 'c';
}else if (xcord <= 0 && ycord <= 0){
terrain = 'w';
}else {
terrain = 'l';
}
}
double minDistanceTo;
int xcord;
int ycord;
short precedingPokemonIndex;
bool visited;
char terrain;
};
void readFile(){
cin >> numPokemon;
int xcord, ycord;
int index = 0;
size_t index = 0;
pokeDex.resize(numPokemon);
while (cin >> xcord && cin >> ycord){
Pokemon pokemon(xcord, ycord);
if (!index){
pokemon.minDistanceTo = 0;
}
pokeDex[index] = pokemon;
index++;
pokeDex.push_back(pokemon);
}
}
void findMst(){
vector<size_t> innies;
vector<size_t> outies(pokeDex.size());
iota(outies.begin(), outies.begin() + int(pokeDex.size()), 0);
while (!outies.empty()){
int numVisited = 0;
while (numVisited != int(pokeDex.size())){
double minDistance = numeric_limits<double>::infinity();
size_t minIndex = numeric_limits<size_t>::infinity();
for (size_t i = 0; i < outies.size(); i++){
size_t curPokeIndex = outies[i];
if (pokeDex[curPokeIndex].minDistanceTo < minDistance){
minDistance = pokeDex[curPokeIndex].minDistanceTo;
for (size_t i = 0; i < pokeDex.size(); i++){
if (!pokeDex[i].visited && pokeDex[i].minDistanceTo < minDistance){
minDistance = pokeDex[i].minDistanceTo;
minIndex = i;
}
}
size_t pokemonIndex = outies[minIndex];
innies.push_back(pokemonIndex);
outies.erase(outies.begin() + int(minIndex));
pokeDex[minIndex].visited = true;
numVisited++;
for (size_t i = 0; i < outies.size(); i++){
size_t curPokeIndex = outies[i];
double distance = pokeDistance(pokeDex[pokemonIndex], pokeDex[curPokeIndex]);
if (distance < pokeDex[curPokeIndex].minDistanceTo){
pokeDex[curPokeIndex].minDistanceTo = distance;
pokeDex[curPokeIndex].precedingPokemonIndex = int(pokemonIndex);
for (size_t i = 0; i < pokeDex.size(); i++){
if (!pokeDex[i].visited){
double distance = pokeDistance(pokeDex[minIndex], pokeDex[i]);
if (distance < pokeDex[i].minDistanceTo){
pokeDex[i].minDistanceTo = distance;
pokeDex[i].precedingPokemonIndex = short(minIndex);
}
}
}
......@@ -109,7 +96,19 @@ public:
private:
vector<Pokemon> pokeDex;
int numPokemon;
size_t numPokemon;
double pokeDistance(Pokemon &poke1, Pokemon &poke2){
if ((poke1.terrain == 'l' && poke2.terrain == 'w') || (poke1.terrain == 'w' && poke2.terrain == 'l')){
return numeric_limits<double>::infinity();
}else {
double x = poke1.xcord - poke2.xcord;
double y = poke1.ycord - poke2.ycord;
double dist = (x * x) + (y * y);
dist = sqrt(dist);
return dist;
}
}
};
// Project Identifier: 5949F553E20B650AB0FB2266D3C0822B13D248B0
#include <vector>
#include <cmath>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <limits>
#include "FASTTSP.h"
using namespace std;
class OPTTSP {
public:
class mst2 {
public:
double pokeDistance(size_t pokeIndex1, size_t pokeIndex2, vector<Poke> &pokeDex){
Poke poke1 = pokeDex[pokeIndex1];
Poke poke2 = pokeDex[pokeIndex2];
double x = poke1.xcord - poke2.xcord;
double y = poke1.ycord - poke2.ycord;
double dist = (x * x) + (y * y);
dist = sqrt(dist);
return dist;
}
double getDistance(){
return distance;
}
mst2(vector<int> &x, vector<Poke> &pokeDex, vector<vector<double>> &distanceMatrix){
for (size_t i = 0; i <= x.size(); i++){
Vertex vertex;
vertex.index = (i == x.size()) ? 0 : size_t(x[i]);
if (i == 0){
vertex.minDistanceTo = 0;
}else {
vertex.minDistanceTo = numeric_limits<double>::infinity();
}
vertex.precedingPokeIndex = -1;
vertex.visited = false;
v.push_back(vertex);
}
size_t numVisited = 0;
size_t numToVisit = v.size();
while (numVisited != numToVisit){
double minDistance = numeric_limits<double>::infinity();
size_t minIndex = numeric_limits<size_t>::infinity();
for (size_t i = 0; i < v.size(); i++){
if (!v[i].visited && v[i].minDistanceTo < minDistance){
minDistance = v[i].minDistanceTo;
minIndex = i;
}
}
v[minIndex].visited = true;
numVisited++;
for (size_t i = 0; i < v.size(); i++){
if (!v[i].visited){
double distance = distanceMatrix[v[minIndex].index][v[i].index];
if (distance == 0){
distance = pokeDistance(v[minIndex].index, v[i].index, pokeDex);
distanceMatrix[v[minIndex].index][v[i].index] = distance;
}
if (distance < v[i].minDistanceTo){
v[i].minDistanceTo = distance;
v[i].precedingPokeIndex = short(minIndex);
}
}
}
} //while
double total = 0;
for (size_t i = 0; i < v.size(); i++){
if (v[i].precedingPokeIndex != -1){
total += v[i].minDistanceTo;
}
}
distance = total;
}
struct Vertex {
size_t index;
bool visited;
double minDistanceTo;
short precedingPokeIndex;
};
private:
double distance;
vector<Vertex> v;
};
bool promising(size_t permLength){
if ((path.size() - permLength) <= 5){
return true;
}
auto first = path.begin() + int(permLength);
auto last = path.end();
vector<int> newVec(first, last);
mst2 mst(newVec, pokeDex, distanceMatrix);
double totalDistanceLowerBound = curPathDistance + mst.getDistance();
return totalDistanceLowerBound < bestPathDistance;
}
void genPerms(size_t permLength) {
// Hit a leaf node, without getting pruned off by promising... if it is better than the best path so far, update the best path so far
if (path.size() == permLength) {
// update best path distance if necessary
int temp = distanceMatrix[path[path.size() - 1]][0];
if (temp == 0){
temp = pokeDistance(path[path.size() - 1], 0);
distanceMatrix[path[path.size() - 1]][0] = temp;
}
curPathDistance += temp;
if (curPathDistance < bestPathDistance){
bestPathDistance = curPathDistance;
bestPath = path;
}
curPathDistance -= temp;
return;
}
if (!promising(permLength))
return;
for (size_t i = permLength; i < path.size(); ++i) {
swap(path[permLength], path[i]);
// add to current path length
int temp = distanceMatrix[path[permLength - 1]][path[permLength]];
if (temp == 0){
temp = pokeDistance(path[permLength - 1], path[permLength]);
distanceMatrix[path[permLength - 1]][path[permLength]] = temp;
}
curPathDistance += temp;
genPerms(permLength + 1);
// subtract from current path length to put back how it was
curPathDistance -= temp;
swap(path[permLength], path[i]);
}
} // genPerms()
OPTTSP(){
curPathDistance = 0;
bestPathDistance = numeric_limits<double>::infinity();
}
void solve(){
genPerms(1);
print();
}
void readFile(){
FASTTSP fasttsp;
fasttsp.readFile();
fasttsp.solve();
pokeDex = fasttsp.getPokeDex();
path = fasttsp.getTspPokeDex();
distanceMatrix.resize(pokeDex.size());
for (size_t i = 0; i < pokeDex.size(); i++){
distanceMatrix[i].resize(pokeDex.size());
}
}
private:
friend class mst2;
vector<Poke> pokeDex;
vector<size_t> path;
vector<size_t> bestPath;
double bestPathDistance;
double curPathDistance;
vector<vector<double>> distanceMatrix;
void print(){
cout << bestPathDistance << "\n";
for (size_t i = 0; i < bestPath.size(); i++){
cout << bestPath[i] << " ";
}
cout << "\n";
}
double pokeDistance(size_t pokeIndex1, size_t pokeIndex2){
Poke poke1 = pokeDex[pokeIndex1];
Poke poke2 = pokeDex[pokeIndex2];
double x = poke1.xcord - poke2.xcord;
double y = poke1.ycord - poke2.ycord;
double dist = (x * x) + (y * y);
dist = sqrt(dist);
return dist;
}
};
// Project Identifier: 5949F553E20B650AB0FB2266D3C0822B13D248B0
#ifndef haha
#define haha
#include <iostream>
#include <getopt.h>
#include <iomanip>
#include "MST.h"
#include "FASTTSP.h"
#include "OPTTSP.cpp"
#include "xcode_redirect.hpp"
using namespace std;
void getOptions(int argc, char* argv[], string &mode);
......@@ -19,6 +24,16 @@ int main(int argc, char* argv[]){
Mst mst;
mst.readFile();
mst.findMst();
}else if (mode == "FASTTSP"){
FASTTSP fastTsp;
fastTsp.readFile();
fastTsp.solve();
fastTsp.print();
}else if (mode == "OPTTSP"){
// TODO
OPTTSP opt;
opt.readFile();
opt.solve();
}
return 0;
......@@ -50,3 +65,4 @@ void getOptions(int argc, char* argv[], string &mode){
}
}
#endif
10
454 -340
372 118
292 99
335 148
-288 76
-5 100
-482 366
-75 417
362 231
92 274
10
-155 -337
130 -101
231 489
213 -365
165 -218
297 188
-294 -135
-131 -425
-208 478
460 402
10
-426 -30
-478 472
-485 -472
-4 398
-362 -293
104 -122
-5 27
37 229
-449 -392
-263 317
10
393 -11
-319 281
152 -379
279 -100
-210 -322
17 -189
-167 -45
-160 165
149 409
442 -474
10
-483 11
-305 -402
419 -326
134 219
-154 391
-48 217
415 88
-418 -43
-265 -190
476 417
10
344 429
396 -458
412 147
277 5
280 130
472 116
-322 119
363 322
57 -71
258 360
10
396 -280
0 -407
464 -167
-234 128
-481 86
-377 225
-179 321
-289 465
209 201
-5 -29
10
145 436
-181 -101
-130 82
217 417
248 475
-187 -152
277 145
341 -431
387 112
258 290
10
-434 -273
393 -216
79 -405
30 491
-359 461
237 140
325 138
424 -441
-422 -176
-306 -119
10
18 -446
164 -3
-214 80
423 48
475 -421
-291 38
391 -11
402 427
-378 -323
491 -34
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment