Need help with deep first search (please help)
suppose that i have a distance table
public class DistanceTable{
private String[] legends;
private double[][] length;
public DistanceTable(String[] legends, double[][] length){
this.legends = legends;
this.length = length;
}
public String getLegend(int i){
return legends[i];
}
public double getDistance(int from, int to){
return length[from][to];
}
public int size(){
return legends.length;
}
public static DistanceTable getDefault(){
String[] legends = {"A", "B", "C", "D", "E", "F", "G", "H", "I"};
double[][] distance = {{0.0, 2.1, 3.4, 5.1, 1.1, 1.1, 1.4, 3.2, 4.5},
{1.3, 0.0, 2.1, 3.4, 5.1, 1.1, 1.1, 1.4, 3.2},
{2.5, 5.8, 0.0, 3.4, 5.1, 1.1, 1.1, 1.4, 3.2},
{3.6, 4.3, 6.3, 0.0, 5.1, 1.1, 1.1, 1.4, 3.2},
{4.2, 8.9, 4.5, 7.1, 0.0, 2.1, 3.4, 5.1, 1.1},
{5.9, 6.7, 8.1, 8.6, 7.6, 0.0, 0.0, 2.1, 3.4},
{6.7, 5.4, 7.8, 6.4, 2.4, 4.8, 0.0, 2.1, 3.4},
{7.1, 2.6, 1.6, 2.1, 3.6, 6.3, 7.1, 0.0, 8.6},
{8.4, 7.1, 3.8, 7.6, 1.2, 7.2, 5.5, 2.6, 0.0},
{9.8, 8.6, 1.0, 2.6, 4.5, 1.8, 4.6, 7.5, 9.9},
};
return new DistanceTable(legends, distance);
}
}
and my Main program goes like this
import java.util.Stack;
import java.util.ArrayList;
import java.util.Iterator;
class Main{
public static void main(String[] args){
int desiredCity=0;
DistanceTable dt = DistanceTable.getDefault();
int le= dt.size();
UserIO io=new UserIO(dt);
startingCity=io.getStartingCity(); // Getting the desired city
DfsTSPSolver solver = new DfsTSPSolver(desiredCity);
solver.solve(dt); // Solve the problem
System.out.println("Best Solution: " + solver.getBestSolution());
System.out.printf("Best Solution's length: %.2fkm\n\n" , solver.getBestSolution().getLength());
Solution[] s=solver.getTopTenSolutions();
for(int i=0;i<le;i++){
System.out.print(i+1 + ". ");
System.out.print(s[i] + "\t");
System.out.printf("(%.2fkm)\n" , s[i].getLength());
}
}
public static class DfsTSPSolver implements TSPSolver{
private Solution[] solutions = new Solution[10]; // 10 best path solutions
private double[] solutionsLength=new double[10];// 10 best path solutions length
Stack<Integer> indexStack=new Stack<Integer>(); // Stack to store city indices
private int parent,desiredCity;
// Default city level in tree hierarchy
ArrayList<DfsSolution> topTen=new ArrayList<DfsSolution>();
public DfsTSPSolver(int desiredCity){ //constructor
this.desiredCity=desiredCity;
parent=desiredCity;
}
public DfsTSPSolver(){ //constructor
this.desiredCity=0;
parent=0;
}
public void solve(DistanceTable dt){
int legendSize=dt.size();
// Start tracing the path tree?1
trace(dt,legendSize,1);
// Copy all the topTen Arraylist elements to solutions array
for(int i=0;i<legendSize;i++){
solutions[i]=topTen.get(i);
}
}
public Solution getBestSolution(){
return solutions[0];
}
public Solution[] getTopTenSolutions(){
return solutions;
}
// Trace the path tree to get all the possible path
private boolean trace(DistanceTable dt, int legendSize,int level){
// If the end of city is visited, add the specific path solution to an arraylist for analysis
if(level==legendSize){
if(!indexStack.empty()){
// Get all the stack values and produce a complete path
ArrayList<Integer> sol=new ArrayList<Integer>();
for(int i=0;i<indexStack.size();i++){
sol.add(indexStack.elementAt(i));
}
sol.add(parent);
sol.add(desiredCity);
// Start - Calculate the path total length and sort with the top ten solutions.
DfsSolution path=new DfsSolution(dt,sol);// ARRAYLIST
double tempLength=path.getLength();
int size=topTen.size();
int i=0;
Iterator it=topTen.iterator();
while(true){
if(it.hasNext()){
Solution a=(Solution)it.next();
if(tempLength<a.getLength()){
topTen.add(i,path);
if(size==legendSize)
topTen.remove(legendSize);
break;
}
i++;
}
else if(size<legendSize){
topTen.add(path);
break;
}
else
break;
}
// End - Calculation and Sorting
}
return true;
}
// Push the parent level legend index when moving to the child level
indexStack.push(parent);
for(int i=0;i<legendSize;i++){
if(i==desiredCity)
continue;
if(indexStack.search(i)<0 && parent!=i ){
// If the legend index is not inside the stack
parent=i;
trace(dt,legendSize,level+1);
}
}
// pop out the top stack value after each level
parent =indexStack.pop();
return true;
}
}
public static class DfsSolution implements Solution{
private double length = 0.0;
private String solution = "";
DfsSolution(DistanceTable dt, ArrayList sol){
// Get the specific path solution string and length
Integer legendIndexFrom,legendIndexTo;
for(int i=0;i<sol.size();i++){
legendIndexTo=(Integer)sol.get(i);
if(i!=0){
legendIndexFrom=(Integer)sol.get(i-1);
this.length+=dt.getDistance(legendIndexFrom,legendIndexTo);
this.solution+="->";
}
this.solution+=dt.getLegend(legendIndexTo.intValue());
}
}
public String toString(){
return solution;
}
public double getLength(){
return length;
}
}
}
for this the program could be run smoothly with the output of 10 best path and length. However i need to enhance it, by letting the user to select their desired city, instead of all 9 cities in the distance table.
I know i have to do something with my legendSize and the trace method. but how? :confused:

