Group Abstract Group Abstract

Message Boards Message Boards

Get a pair with smallest total distance from one list

Posted 9 years ago
POSTED BY: Yode Japhe
18 Replies
Posted 9 years ago

Would FindShortestTour be a better choice, (if I have read this correctly) as an example

AbsoluteTiming[SeedRandom[1]; pts = RandomReal[100, {100, 2}]; 
 pair = Partition[pts[[Last[FindShortestTour[pts]]]], 2]; 
 Print[Graphics[{Line[pair], Red, PointSize[.015], Point[pts]}]]; 
 Total[Table[
   Sqrt[(pair[[q, 1, 1]] - pair[[q, 2, 1]])^2 + (pair[[q, 1, 2]] - 
      pair[[q, 2, 2]])^2], {q, 1, Length[pair]}]]]

or by rotating the points by 1 to get the other possible set of pairs

AbsoluteTiming[SeedRandom[1]; pts = RandomReal[100, {100, 2}]; 
 pair = Partition[pts[[Last[FindShortestTour[pts]]]], 2]; 
 pair = Partition[RotateLeft[Flatten[pair, 1]], 2]; 
 Print[Graphics[{Line[pair], Red, PointSize[.015], Point[pts]}]]; 
 Total[Table[
   Sqrt[(pair[[q, 1, 1]] - pair[[q, 2, 1]])^2 + (pair[[q, 1, 2]] - 
      pair[[q, 2, 2]])^2], {q, 1, Length[pair]}]]]

in comparison to this method

AbsoluteTiming[SeedRandom[1]; pts = RandomReal[100, {100, 2}]; 
 g = CompleteGraph[Length[pts]]; 
 verGraph = VertexReplace[g, Thread[VertexList[g] -> pts]]; 
 weighGraph = 
  Graph[verGraph, 
   EdgeWeight -> EuclideanDistance @@@ EdgeList[verGraph]]; 
 pair = Partition[FindHamiltonianPath[weighGraph], 2]; 
 Print[Graphics[{Line[pair], Red, PointSize[.015], Point[pts]}]]; 
 Total[Table[
   Sqrt[(pair[[q, 1, 1]] - pair[[q, 2, 1]])^2 + (pair[[q, 1, 2]] - 
      pair[[q, 2, 2]])^2], {q, 1, Length[pair]}]]]

The shortest tour option is also much faster, 3000 points is under a second on my machine.

POSTED BY: Paul Cleary

This does not give the minimum pairs, see my reply above: http://community.wolfram.com/groups/-/m/t/1075278

Mainly you're minimizing the total length rather then the even (or odd) pieces. But it can be a good starting point for other algorithms to improve on it. But certainly does not guarantee minimal solution.

POSTED BY: Sander Huisman
Posted 9 years ago

Could I know how do you get that url(http://community.wolfram.com/groups/-/m/t/1075278) about a reply under a post?

POSTED BY: Yode Japhe

source of the webpage...

POSTED BY: Sander Huisman
Posted 9 years ago
POSTED BY: Alexey Popkov

That's kinda what I meant, if you click 'inspect element' on most parts of the post, you can see the ID all over the place...

POSTED BY: Sander Huisman
Posted 9 years ago

Thanks for your endeavor for my this question.And I think a good message deserve to bring to you.I receive a good solution here based on FindShortestTour.

POSTED BY: Yode Japhe
Posted 9 years ago
POSTED BY: Yode Japhe
POSTED BY: Sander Huisman
Posted 9 years ago

Oh,a minimum cost perfect matching can serve many case,just we cannot realize it sometimes.I can think out right now another two examples I have encoutered.

Actually I can consider it as a minimum cost perfect matching question,and in such case,a local minimum, but not a global minimum, will lead to a disastrous result.And the link,I cited, work for this indeed as I know.

POSTED BY: Yode Japhe
Posted 9 years ago

I have a method based on FindHamiltonianPath.It has a not very bad efficiency,which can find a pair(it is not always a global minimum pair as my test) from 100 points within 1s

SeedRandom[1]
pts = RandomReal[100, {100, 2}];
g = CompleteGraph[Length[pts]];
verGraph = VertexReplace[g, Thread[VertexList[g] -> pts]];
weighGraph = 
  Graph[verGraph, 
   EdgeWeight -> EuclideanDistance @@@ EdgeList[verGraph]];
pair = Partition[FindHamiltonianPath[weighGraph], 2];
Graphics[{Line[pair], Red, PointSize[.015], Point[pts]}]

Mathematica graphics

It is not a perfect solution,because a global minimum pair always is ecpected actually.

POSTED BY: Yode Japhe
POSTED BY: Sander Huisman
Posted 9 years ago

The blue ones always is the real minimum pair?

POSTED BY: Yode Japhe

A better minimum as compared to the black one. I'm not sure if it is THE minimum. You can see that some pairs 'switched', especially clear in the top right with the 'triangle'.

POSTED BY: Sander Huisman
Posted 9 years ago
POSTED BY: Yode Japhe
POSTED BY: Sander Huisman
Posted 9 years ago

Brilliant try.Thanks very much.

But if I give some test pts for test,I found it not always give a right answer?Such as

SeedRandom[1]
pts = RandomReal[100, {8, 2}]

{{81.7389,11.142},{78.9526,18.7803},{24.1361,6.57388},{54.2247,23.1155},{39.6006,70.0474},{21.1826,74.8657},{42.2851,24.7495},{97.7172,82.5163}}

If we use a brute force method to find a definitely right answer:

First[pairs = 
  MinimalBy[Partition[#, 2] & /@ Permutations[pts], 
   Total[EuclideanDistance @@@ N[#]] &]]
First[Total[EuclideanDistance @@@ N[#]] & /@ pairs]

{{{81.7389,11.142},{78.9526,18.7803}},{{24.1361,6.57388},{42.2851,24.7495}},{{54.2247,23.1155},{97.7172,82.5163}},{{39.6006,70.0474},{21.1826,74.8657}}}

126.475(This is total distance)

But If we use your FindPairs

pts[[#]] & /@ FindPairs[pts]
Total[EuclideanDistance @@@ N[pts[[#]] & /@ FindPairs[pts]]]

{{{24.1361,6.57388},{54.2247,23.1155}},{{81.7389,11.142},{78.9526,18.7803}},{{39.6006,70.0474},{21.1826,74.8657}},{{42.2851,24.7495},{97.7172,82.5163}}}

141.565(This is total distance)

POSTED BY: Yode Japhe
POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard