1

I need to find optimal path between a number of points on a 2d map. The 2d map is of a building and will simply have where you can not go (through walls) and all the points on the map. So it's not really a map, rather lines you cannot go through with points to pass through.

  • I have a number of points, say between 20 and 500
  • I start with one that I select and then need the route calculated for most optimal path.

I would love hints for where to look for this travelling salesman problem with obstacles. Or even better, done library for doing it.

Bonuses

  • Things like doors can be weighted as they are less fun to pass through back and forth.
  • Possibility of prioritizing/Weighting the ability to end close to where you started.
  • Selecting areas as passable but annoying (weighting down)
  • .Net/C# code that I can use, I want to use this both on .NET MVC project and Xamarin mobile project so .net code would be great (if code exists)

Update example

enter image description here In my example here we have an office. Now I have not thought every detail out so this is merely an example.

  • All the purple dots need to be checked
  • Yellow area could mean annoying to pass through but doable
  • Red could mean not active but can be passed if no other option exists.
  • Blue (walls) are impenetrable and can not be passed.
  • Green is doors, weighted down possibly as it's annoying to go trough closed doors (usually this would probably make sense anyway as the dots in a room would be easiest to check together.
  • The user would go to one dot, check it, then the software should tell him which one to do next until he is done.
  • Bonus could be given for ending close to start place. So for instance in this example, if the red area was normal and contained dots it would have been easy to make it a loop. (So the user comes back close to where he started)
  • Finally I suppose it would also be smart to differentiate outdoors areas as you would need to get dressed for outdoors, so you only want to go out once.
  • Also it could be smart to be able to prioritize ending on a point close to stairwell to next floor if they intend to check multiple floors at once.
  • Of course would have more more complex and larger plans the this exmaple.

Again sorry for just brainstorming out ideas but I have never done this kind of work and is happy for any pointers :-)

Rickard Liljeberg
  • 966
  • 1
  • 12
  • 39
  • 1
    Your constraints about obstacles sound like you simply need to include a penalty weight on edges between nodes that meet some criteria as a step when building your representation of the graph before you actually try to do a tsp solve. I'm also not convinced that a tsp is a great representation of a building route, given that rooms in a building aren't really going to form a connected graph. – Preston Guillot Feb 08 '15 at 18:33
  • True maybe TSP is not the best solution but I am still keen to hear suggestions on good solutions to my problem. – Rickard Liljeberg Feb 08 '15 at 19:33
  • 1
    Are you looking for the shortest path from point A to point B with no requirement about which nodes you pass through on the way? Or are you required to pass through every node? If #1, it's a shortest-path problem, not a TSP -- much easier. In either case, I agree with @PrestonGuillot that you probably can just build the obstacles into the edge weights -- set them to infinity if you can't go from one node directly to another. You can do the same for prioritizing/discouraging doors, annoying areas, etc. Another option is to use a multi-objective optimization approach but this might be overkill. – LarrySnyder610 Feb 08 '15 at 20:52
  • I need to go to all points, it's about making controls. A human need to control items in a building, all things need to be checked, the starting point will be the first item the human checks. I have never worked with this kind of problem before so I don't fully understand your edge weights. I would love if you elaborated. I will upload a photo to show an example. – Rickard Liljeberg Feb 08 '15 at 21:27

1 Answers1

2

Let N be the set of nodes to visit (purple points). For each i and j in N, let c(i,j) be the distance (or travel time) to get from i to j. These can be pre-computed based on actual distances plus walls, doors, other barriers, etc.

Now, you could then add a penalty to c(i,j) if the path from i to j goes through a door, "annoying" area, etc. But a more flexible way might be as follows:

Let k = 1,...,K be the various types of undesirable route attributes (doors, annoying areas, etc.). Let a_k(i,j) be the amount of each of these attributes on the path from i to j. (For example, suppose k=1 represents door, k=2 represents yellow areas, k=3 represents outside. Then from an i in the break area to j in the bathroom might have a_1(i,j) = 1, and from an i to a j both in the yellow areas would have a_2(i,j) = 0.5 or 2.0 or however annoying that area is, etc.)

Then, let p_k be a penalty for each unit of undesirable attribute k -- maybe p_1 = 0.1 if you don't mind going through doors too much but p_2 = 3.0 if you really don't like yellow areas.

Then, let c'(i,j) = c(i,j) + sum{k=1,...,K} p_k * a_k(i,j). In other words, replace the actual distance with the distance plus penalties for all the annoyances. The user can set the p_k values before the optimization in order to express his/her preferences among these. The final penalties p_k * a_k(i,j) should be commensurate with the distance units used for c(i,j), though -- you don't want distances of 100m but penalties of 1,000,000.

Now solve a TSP with distances given by c'(i,j).

The TSP requires you to start and end at the same node, so that preference is really a constraint. If you're going to solve for multiple floors simultaneously, then the stairway times would be in the c(i,j) so there's no need to explicitly encourage routes that end near a stairway -- the solution would tend to do that anyway since stairs are slow. If you're going to solve each floor independently, then just set the start node for each floor equal to the stairway. I wouldn't do anything about the red (allowable but unused) areas -- that would already be baked into the c(i,j) calculations.

Hope this helps.

LarrySnyder610
  • 2,277
  • 12
  • 24
  • Fantastic answer, but I am left with 3 questions. 1. What is the best way to calculate the route (and distance) between points (taking into consideration that the amount of doors can change the route to a longer but easier.) - This could be a question of it's own on stack so can be ignored. I post the other two questions below for readability. – Rickard Liljeberg Feb 09 '15 at 08:53
  • 2. If I have 500 points and have to calculate c(i, j) for them all it will be incredible amounts of data (I need this on mobile as well as web and will have many buildings). How can I make this smarter and with less data, so that it's reasonable amount? I am okay with recalculating things and storing the result but it can't be ridiculous amounts of data to send to the mobile. – Rickard Liljeberg Feb 09 '15 at 08:54
  • 3. Hints on modifying the TSP so that I rather visit all points than return home after, this way I could also have bonuses for finish close to places like stairs to next floor. The user will probably always start closest to his desk and ending up there again is a bonus but not so much that it should be a requirement. – Rickard Liljeberg Feb 09 '15 at 09:03
  • 1
    1. The easiest way is probably to divide the map into discrete points (nodes) and then add an edge to the network between two points if you can reach one directly from the other. Set the length of edge `(i,j)` equal to the distance/travel time from `i` to `j`. Solve the shortest-path problem on this network using Dijkstra's algorithm -- this gives you the `c(i,j)` between all `i` and `j`, not just those you can reach directly from one another. Dijkstra's is very efficient and can give you all pairs, quickly, even for 500+ nodes. I'm sure there is source code online. – LarrySnyder610 Feb 09 '15 at 14:48
  • 1
    2. I'm not sure how to reduce the data storage/transmission requirements. Probably you could eliminate, say, the largest x% of the `c(i,j)` since the optimal TSP tour will probably not use them. It will be a tradeoff: larger x means faster but less accurate. Maybe other people have other ideas about this one. – LarrySnyder610 Feb 09 '15 at 14:50
  • 1
    3. TSP will probably encourage this even without you having to do anything. If the user doesn't want to walk the last leg (back to the start point) s/he can just ignore it. But the solution will tend to choose a final node that is close to the start node. If you definitely want the algorithm to ignore the last leg, you can set `c(i,0) = 0` for all i (where 0 is the start node) so that the route can end anywhere, and then maybe add penalties/rewards for ending nodes you like. But then your distance matrix becomes asymmetric, and not all TSP algorithms work well for asymmetric matrices. – LarrySnyder610 Feb 09 '15 at 14:52