Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
72 views

Tsp-Shortest Path-Route-Finding-With-An-Elaborate-Text-File-Csv-Format-Reader

This document contains Java code for finding the shortest closed loop tour of US cities using the shortest path algorithm. It imports necessary classes, defines input and network classes, and includes a main method that initializes a network from input data, runs Dijkstra's algorithm from each starting node to find the minimum cost closed loop, and writes the results to a file. The code comments describe that it finds the shortest closed loop route by trying each city as the starting point and returning the lowest total loop cost.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views

Tsp-Shortest Path-Route-Finding-With-An-Elaborate-Text-File-Csv-Format-Reader

This document contains Java code for finding the shortest closed loop tour of US cities using the shortest path algorithm. It imports necessary classes, defines input and network classes, and includes a main method that initializes a network from input data, runs Dijkstra's algorithm from each starting node to find the minimum cost closed loop, and writes the results to a file. The code comments describe that it finds the shortest closed loop route by trying each city as the starting point and returning the lowest total loop cost.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 36

import java.io.

File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.net.URL;
import java.io.InputStream;
import java.util.Scanner;

//---

/*
* An algorithm to find the shortest
closed loop of a tour of the US cities.
* EEDP Algorithms II:March 2011
* Caesar & Umang
*This note was added on Nov 12 2019 as
*I was uploading this document on
*scribd: I wrote this Java version—and
*Umang wrote his version in C language.
*/
public class HelloWorld {
public static void main(String[]
args ) throws Exception
{
long
startTime=System.currentTimeMillis();

InputMatrix im=new InputMatrix();


PDReader reader=new PDReader();

//URL url = new


URL("https://s3.amazonaws.com/Academia
IndustryResearch/fundamentals/ACOURSE/
AlgorithmsII/TSP/src/homework/alg2data
/TSP_Data.csv");
//File f = new
File( URLDecoder.decode( url.getFile(),
"UTF-8" ) );

im.lengths=
reader.readDistMatrix("alg2data/TSP_Da
ta.csv");

im.columnNames=reader.readCityNames
("alg2data/TSP_Data.csv",
im.lengths[0].length);
//("alg2data/TSP_Data.csv",
im.lengths[0].length);
double
minCost=99999999999.0;//we can think
of a better of way of initializing
these following 2 values
double minCost2=99999999999.0;

NodeEntry[] cheapestRoute= null;


NodeEntry[] shortestPath= null;
Network net=null;
double totalCost=0.0;

//@TO DO:
//We could parallelize the
following independent executions
//
//How it works:
//Each node/city is taken, in
turn, as a starting node- and the
shortest path algorithm is
//invoked. The shortest closed
loop (option 1 or option 2 -- pending
clarification) is the returned.
//
======================================
======================================
======================================
===============
//
======================================
======================================
======================================
===============

for(int m=0; m<1; m++)


//im.columnNames.length is the number
of nodes/cities
{
net=new Network(im, m,
minCost);

if(net.perm[net.perm.length-
1].distancePortion <minCost) //option
1- we'll seek clarification whether
it's option 1 required, or option 2
below
{
totalCost=
GraphOutput.getClosedLoopCost(net.perm
);

minCost=net.perm[net.perm.length-
1].distancePortion;
cheapestRoute=net.perm;
}

for(int m=1;
m<im.columnNames.length; m++)
//im.columnNames.length is the number
of nodes/cities
{
net=new Network(im, m,
net.perm[net.perm.length-
1].distancePortion);

if( net.perm.length
==im.columnNames.length &&
net.perm[net.perm.length-
1].distancePortion <=minCost)
//option 1- we'll seek clarification
whether it's option 1 required, or
option 2 below
{
totalCost=
GraphOutput.getClosedLoopCost(net.perm
);
minCost=net.perm[net.perm.length-
1].distancePortion;
cheapestRoute=net.perm;
//System.out.println("
Attempting to compute shortest path
starting at "+ im.columnNames[m] +"...
NEW SHORTEST PATH FOUND at " +
net.perm.length);
}
{

//System.out.println("
Attempting to compute shortest path
starting at "+ im.columnNames[m] +"...
Aborted at " + net.perm.length);
}

}
//end of parallelization
//
======================================
======================================
======================================
===============
//
======================================
======================================
======================================
===============

//write to file the loop that


minimizes the entire loop
FileWriter writer =new
FileWriter("alg2output/output.txt");

String LS =
System.getProperty("line.separator");

writer.write("Least cost is "+


totalCost);
writer.write(LS+LS);
long
endTime=System.currentTimeMillis();
writer.write("Average Execution
time: "+ (endTime-startTime)+" ms");

//write route to file


writer.write(LS+LS +" ");
writer.write(LS +" Least closed
loop");
writer.write(LS+LS +" ----------
-------");
for(int
i=0;i<cheapestRoute.length;i++)
{
writer.write(LS+" --
>"+cheapestRoute[i].nodeName);

}
writer.close();

System.out.println("... DONE.
See output in TSP/alg2output");

}
}

/*
*
* Class defines the column names and
lengths
*/
class InputMatrix
{
static String[] columnNames=null;
static double [][] lengths=null;

}
//Add the other classes

class PDReader {

public double [][]


readDistMatrix(String fileName) throws
IOException
{

ArrayList<ArrayList<Double>> pd
= new ArrayList<ArrayList<Double>>();
BufferedReader input= new
BufferedReader(new
FileReader(fileName));
String s =
input.readLine();//read and ignore
this first row
s = input.readLine(); //now
start from here - row 1

int instance = 0;
while ((s != null))
{
pd.add(new
ArrayList<Double>());
StringTokenizer st = new
StringTokenizer(s, ",");
int count=0;
while (st.hasMoreTokens())
{

if(count<2)
{
String n
=st.nextToken();
}
else
{
pd.get(instance).add((Double.parseD
ouble((st.nextToken()).toString())));

}
count=count+1;

}
instance=instance+1;
s = input.readLine();
}

double [][] lengths = new


double[pd.get(0).size()][pd.get(0).siz
e()];
for(int i=0; i<pd.get(0).size();
i++)
{
for(int j=0;
j<pd.get(0).size(); j++)
{

lengths[i][j]=pd.get(i).get(j);

}
return lengths;
}

public String[]
readCityNames(String fileName, int len)
throws IOException
{

String[] cityNames=new
String[len];
BufferedReader input= new
BufferedReader(new
FileReader(fileName));
String s =
input.readLine();//read 1st row

StringTokenizer st = new
StringTokenizer(s, ",");
String n =st.nextToken(); // we
don't want the first token, "Cities"
int count=0;
while (st.hasMoreTokens())
{

cityNames[count]=st.nextToken();

cityNames[count]=cityNames[count]+",
"+st.nextToken();
count++;
}

return cityNames;

//also added

/*
* This class defines the special
attributes of any node in a network
*
*/

class NodeEntry
{
String nodeName;
String nodeLabel; //unlabeled,
tentative or permanent
double distancePortion;
//Cumulative distance to a node, -1 if
undetermined
String prevNode; //previous node,
initially set to "-"

NodeEntry(String name, String


label, double dp, String prev)
{
nodeName=name;
nodeLabel=label;
distancePortion=dp;
prevNode=prev;
}
}

//-----

/*
* Implementation of shortest path
algorithm, otherwise also known as the
"labeling procedure"
* The following class defines a set
of rules for instantiating
* the nodes in a given (transport)
network, and contains methods for
* implementing the Shortest Path
Algorithm or Dijkstra's procedure
*/

class Network
{

//change this
int graphSize;
NodeEntry[] node;;
static NodeEntry[] tempCpy;;
static double[][] directLength;;

//declaration of an array to store


permanently labeled nodes
//(those removed from the initial
nodes array)
static NodeEntry[] perm=null;

//declaration of an array to
temporarily store remaining nodes
NodeEntry[] temp =null;

public static String currentLoc,


destination;

Network(InputMatrix im, int m,


double minCost) throws IOException
{
graphSize=im.lengths[0].length;
node=new NodeEntry[graphSize];
//array to store node
tempCpy=new NodeEntry[graphSize];
//array to store node
directLength=new
double[graphSize][graphSize];

for(int i=0;i<node.length;i++)
{
node[i]=new
NodeEntry(im.columnNames[i],"un",-1,"-
");
}

for(int row=0;
row<directLength.length; row++)
{
for(int col=0;
col<directLength.length; col++)
directLength[row][col]=im.lengths[r
ow][col];
}

perm=new NodeEntry[node.length];
temp =new NodeEntry[node.length];

//get copy for reconstruction


purposes
dupCpy();
get_S_and_D(im.columnNames[m],
"this doesn't matter");
runDijkstra(minCost);
}

/*
* make a cpy of the node names in
their resp position
* before any destruction is done
by Dijkstra's procedure
*
*/
void dupCpy()
{
for(int i=0;i<node.length;i++)
{
tempCpy[i]=new
NodeEntry(node[i].nodeName,node[i].nod
eLabel,node[i].distancePortion,node[i]
.prevNode);
}
}

/*
* method to set source and
destination as selected as input by
user
*
*/
public void get_S_and_D(String
source, String dest)
{
currentLoc=source;
destination=dest;
}

/*
* method to label source (node)
permanent, or "perm"
*
*/
public void setSourcePermanent()
{
for(int i=0;i<node.length;i++)
{

if(node[i].nodeName.equals(currentL
oc))
{
node[i].nodeLabel="perm";
//set source node permanent
node[i].prevNode="S"; //S
denotes "source"
node[i].distancePortion=0;
//
}
}
}

/*
*
* method to copy permanent node
details from node array into perm
array
* Each new permanent node element
is added to the next empty slot in
perm
*/

public void addToPermList()


{
for(int i=0;i<node.length;i++)
{

if(node[i].nodeLabel.equals("perm"))
{
{

perm[currentPermIndex()+1]=
new
NodeEntry(node[i].nodeName,node[i].nod
eLabel,node[i].distancePortion,node[i]
.prevNode);
}
}
}
}

/*
*
* method to copy and return the
non-permanent node array elements
*/

NodeEntry[] remainder()
{
temp=new NodeEntry[node.length-
1];
int k=0;
for(int i=0; i<node.length;i++)
{

if(!(node[i].nodeLabel.equals("perm
")))
{
temp[k]=new
NodeEntry(node[i].nodeName,
node[i].nodeLabel,
node[i].distancePortion,
node[i].prevNode);
k++;
}
}
return temp;
}

/*
* method to determine and return
the index of the most recently
* added element in the perm array
(list).
* A new permanent node,if any, is
added the next slot
*
*/
int currentPermIndex()
{
for(int i=0;i<perm.length;i++)
{
if(perm[i]==null)
return i-1; //(i-1) is the
index of last-in element so far; it's
all null after this
}
return -1;
}

public static int directRow(int


index)
{

for(int i=0; i<tempCpy.length;


i++ )
{

if(perm[index].nodeName.equals(temp
Cpy[i].nodeName))
{
return i;
}
}
return -1;
}

public static int directCol(String


name)
{

for(int i=0; i<tempCpy.length;


i++ )
{

if(name.equals(tempCpy[i].nodeName))
{
return i;
}
}
return -1;

/*
*
* method to remove the permanent
node from the previous nodes array
*/

public void remove()


{
NodeEntry[] ne=remainder(); //save
reference to remaining array in ne
node=new NodeEntry[ne.length];
//new node length decremented
for(int i=0; i<ne.length;i++)
{
if(ne[i]!=null)
node[i]=new
NodeEntry(ne[i].nodeName,ne[i].nodeLab
el,ne[i].distancePortion,ne[i].prevNod
e);
}
}

/*
* method to determine whether a
given node in the remaining nodes
array
* has direct link to the "current"
permanent node
* This is based on the value of
distance in the distance grid
* A positive distance means
"direct link" exists
*/
boolean isDirectNode(int sub)
{
if((directLength[directRow(currentP
ermIndex())]

[directCol(node[sub].nodeName)])>0)
{
return true;
}
return false;
}

/*
*
* method to revise the tentatively
labeled (temporary) node elements
*/
public void revise()
{
if(numberOfRemainingNodes()>=2)
{
int
x=directRow(currentPermIndex());
//Now from the second
iteration, the link/distance (in
directLength 2-D)
// between the current
permanent node and the node labeled
permanent
//in the preceding iteration
is no longer needed. It may be
discarded.
// Here,it's flagged with the
special integer value,0. Any neg,
other
//than -1 would do.
int z;
//revise all direct nodes
for(int i=0;i<node.length;i++)
{
if(isDirectNode(i))
{

z=directCol(node[i].nodeName);
{

node[i].distancePortion=
perm[currentPermIndex()].distancePorti
on + directLength[x][z];
node[i].prevNode=
perm[currentPermIndex()].nodeName;
}
}
}
}
}
/*
* method to determine and return
the first node slot which contains
* a positive value of cumulative
distance, it is an optimization
* algorithm, saving the caller
from testing for 'positivity' of all
such slot entries
*
*/

int firstPosIndex()
{
for(int i=0;i<node.length;i++)
{
if(node[i].distancePortion>0)
return i;
}
return -1;
}
/*
* method to determine and return
the index of the slot containing the
* minimum (positive) cumulative
distance from the remaining nodes
array
* 1.initializing i to
firstPosIndex() value is an
optimization strategy
* 2.initializing minimum ensures
exact correctness
*
*/

public double min()


{
double
minimum=node[firstPosIndex()].distance
Portion;
for(int
i=firstPosIndex();i<node.length;i++)
{
if(node[i].distancePortion>=0
&& node[i].distancePortion<minimum)

minimum=node[i].distancePortion;
}
}
return minimum;
}
/*
* method to determine and return
index of the min of the revised nodes
*/
int minIndex()
{
for(int i=0;i<node.length;i++)
{

if(node[i].distancePortion==min())
return i;
}
return -1;
}

/*
* method to label a new node
permanent or "perm", basing on the
minimum
* value of the cumulative
distances of the node. Check the
series of
* method calls in this method
activation
*
*/
public void setNewPermNode()
{
//set new permanent node
for(int i=0;i<node.length;i++)
{

if(node[i].distancePortion==min())
{

node[minIndex()].nodeLabel="perm";
}
}
}

/*
* method to return the number of
nodes remaining in a given iteration
*/
public int numberOfRemainingNodes()
{
return node.length;
}

/*
* method to determine and return
the perm node that has the shortest
* direct path to the next
specified perm node as determined by
the
* Dijkstra's rule for given a
source-destination problem
*/
int prevNodeIndex(String
currentNodeName)
{
if( node.length==1) //base case
perm[perm.length-1]=new
NodeEntry(node[0].nodeName,node[0].nod
eLabel,node[0].distancePortion,node[0]
.prevNode);
//the following executes only n-
1, where n=number of the network nodes
for(int j=0;j<perm.length;j++)
{

if(perm[j].nodeName.equals( current
NodeName))
return j;
}
return -1;
}

/*
* method to invoke all the methods
in some sequence to implement
Dijkstra's procedure
*/
double minTotalCost=999999999.0;
NodeEntry[] leastCostPath=perm;
void runDijkstra(double minCost)
throws IOException
{
setSourcePermanent();
int i=0;
int p=0;
do
{
addToPermList();
revise();
remove();
setNewPermNode();
i++;

if (currentPermIndex()>0)
{
p=currentPermIndex();
//perm[perm.length-
1].distancePortion=perm[p].distancePor
tion;
}
}while(numberOfRemainingNodes()>0
&& perm[p].distancePortion< minCost);

/*for(int j=0;j<perm.length;j++)
{
System.out.println( j+ ": "
+perm[j].distancePortion);
}*/

}//end of Nodes class

//--------------

class GraphOutput {
public static double
getClosedLoopCost(NodeEntry[] path)
throws IOException
{

double cost=0.0;
double totalCost=0.0;

cost=path[path.length-
1].distancePortion ;
double costBack=
Network.directLength[Network.directCol
(path[0].nodeName)][Network.directCol(
path[path.length-1].nodeName)];
totalCost=(cost +costBack);

return totalCost;
}

You might also like