0

I understand the travelling salesman problem. Suppose if I want to visit only selected cities and come back to start, how to do that?

Lets say my cost matrix is,

  A B C D
A 0 1 2 1
B 1 0 1 2
C 2 1 0 1
D 1 2 1 0

If I want to visit all the cities and come back to A. My shortest path would be A->B->C->D and min distance would be 4.

Suppose lets say if I want to visit only B and D. How can I find the min distance?

This is modified travelling salesman problem? Can someone help me with doing brute force algo for this case?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user1554472
  • 47
  • 4
  • 9

2 Answers2

1

You can run first Floyd-Warshall to compute the shortest paths between all pairs of nodes. See wikipedia article. Once you have the condensed cost matrix you can eliminate all cities that you are not interested in. From there it's the standard traveling salesman.

Since traveling salesman is NP complete it doesn't matter for complexity that you run Floyd-Warshall before it.

If you want the complete directions (including detours through uninteresting cities to make the paths shorter you'll have to go back to the Floyd-Warshall and reconstruct the paths.

Sorin
  • 11,863
  • 22
  • 26
0

I don't have my code handy, but here's some suggestions and pseudocode to get you going: I would solve this by storing a vector as well as your above distance matrix in memory. Something like:

struct Location{
bool visited;
bool mustVisit;
}

Vector<Location> locationVec;

Populate the vector with the locations in your problem, marking whether or not they have to be visited, and always setting visited to false. Then comes the fun part! You need to create permutations of the locationVec. I would do this recursively, something like:

void addLocation(int & curLength, int & maxLength, int & curDistance, Vector<Location> &locationVec, Location* lastVisited)
if(curLenth == maxLength){
//check if currentDistance is less than the previously generated best difference, if so
//replace it
lastVisited->visited=0;
return;
}

//Add the next location
for (int& i : locationVec){
//Check if the location has been visited, and if it must be visited.
//If so: mark as visited, point lastVisited to it, and break
//Also add from lastVisited to the new location to your curDistance
curLength++;
}

addLocation(curLength, maxLength, curDistance, locationVec, lastVisited);
return;
}

That should get you started. Remember to subtract from currentDist when you change visited from visited = 1 to visited = 0, because you're essentially "unvisiting" the city. You may need to keep track of lastlastvisited as well, depending on your exact implementation.

If you need to speed it up (and you probably will, traveling Salesman is very slow), look into Branch and Bound: http://en.wikipedia.org/wiki/Branch_and_bound

PunDefeated
  • 566
  • 5
  • 18
  • Sorry but that can't be done, I'm on the wrong continent. Also can't share it without getting expelled from school :D – PunDefeated Aug 07 '13 at 08:03