Skip to main content
deleted 42 characters in body
Source Link
ybeltukov
  • 43.9k
  • 5
  • 109
  • 215

Minimization of the total Euclidean distance from balls to holes is quite difficult optimization problem (I'm not sure, may be it is a NP-problem). As a start point I propose a simple greedy algorithm:

  • Find the nearest hole for every ball.
  • Put balls to holes starting from the closest ball-hole pair while the corresponding holes are empty
  • Repeat

It is not the best algorithm and may be I will update my post in the future.

n = {5, 5};
holes = N@Tuples@Range@n;
balls = RandomReal[{0, # + 1}, Times @@ n] & /@ n // Transpose;

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], Point[balls]}]

enter image description here

res = Flatten[#, 2] &@ Last@Reap@
    Module[{h = holes, b = balls, nh, nb, nf, num, put, fill, 
      nondup},
     nb = nh = Range@Length@h;
     While[h != {},
      nf = Nearest[h -> Automatic];
      num = nf /@ b // Flatten;
      put = Ordering@Total[(h[[num]] - b)^2, {2}];
      fill = num[[put]];
      nondup = Floor@BinarySearch[Range@Length@fill, 1/2, 
         1 - Boole@DuplicateFreeQ@fill[[;; #]] &];
      put = put[[;; nondup]];
      fill = fill[[;; nondup]];
      Sow@Transpose@{nb[[put]], nh[[fill]]};
      b = Delete[b, Transpose@{put}];
      nb = Delete[nb, Transpose@{put}];
      h = Delete[h, Transpose@{fill}];
      nh = Delete[nh, Transpose@{fill}];
      ]
     ]
(* {{8, 24}, {13, 5}, {19, 16}, {23, 10}, {1, 23}, {3, 17}, {5,
   14}, {16, 21}, {17, 3}, {9, 8}, {7, 4}, {18, 11}, {4, 22}, {21, 
  15}, {11, 20}, {2, 6}, {14, 2}, {10, 7}, {15, 9}, {25, 1}, {12, 
  25}, {6, 18}, {22, 19}, {20, 13}, {24, 12}} *)

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], 
  Point[balls], Arrow[{balls[[#]], holes[[#2]]} & @@@ res]}]

enter image description here

Minimization of the total Euclidean distance from balls to holes is quite difficult optimization problem (I'm not sure, may be it is a NP-problem). As a start point I propose a simple greedy algorithm:

  • Find the nearest hole for every ball.
  • Put balls to holes starting from the closest ball-hole pair while the corresponding holes are empty
  • Repeat

It is not the best algorithm and may be I will update my post in the future.

n = {5, 5};
holes = N@Tuples@Range@n;
balls = RandomReal[{0, # + 1}, Times @@ n] & /@ n // Transpose;

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], Point[balls]}]

enter image description here

res = Flatten[#, 2] &@ Last@Reap@
    Module[{h = holes, b = balls, nh, nb, nf, num, put, fill, 
      nondup},
     nb = nh = Range@Length@h;
     While[h != {},
      nf = Nearest[h -> Automatic];
      num = nf /@ b // Flatten;
      put = Ordering@Total[(h[[num]] - b)^2, {2}];
      fill = num[[put]];
      nondup = Floor@BinarySearch[Range@Length@fill, 1/2, 
         1 - Boole@DuplicateFreeQ@fill[[;; #]] &];
      put = put[[;; nondup]];
      fill = fill[[;; nondup]];
      Sow@Transpose@{nb[[put]], nh[[fill]]};
      b = Delete[b, Transpose@{put}];
      nb = Delete[nb, Transpose@{put}];
      h = Delete[h, Transpose@{fill}];
      nh = Delete[nh, Transpose@{fill}];
      ]
     ]
(* {{8, 24}, {13, 5}, {19, 16}, {23, 10}, {1, 23}, {3, 17}, {5,
   14}, {16, 21}, {17, 3}, {9, 8}, {7, 4}, {18, 11}, {4, 22}, {21, 
  15}, {11, 20}, {2, 6}, {14, 2}, {10, 7}, {15, 9}, {25, 1}, {12, 
  25}, {6, 18}, {22, 19}, {20, 13}, {24, 12}} *)

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], 
  Point[balls], Arrow[{balls[[#]], holes[[#2]]} & @@@ res]}]

enter image description here

Minimization of the total Euclidean distance from balls to holes is quite difficult optimization problem. As a start point I propose a simple greedy algorithm:

  • Find the nearest hole for every ball.
  • Put balls to holes starting from the closest ball-hole pair while the corresponding holes are empty
  • Repeat

It is not the best algorithm and may be I will update my post in the future.

n = {5, 5};
holes = N@Tuples@Range@n;
balls = RandomReal[{0, # + 1}, Times @@ n] & /@ n // Transpose;

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], Point[balls]}]

enter image description here

res = Flatten[#, 2] &@ Last@Reap@
    Module[{h = holes, b = balls, nh, nb, nf, num, put, fill, 
      nondup},
     nb = nh = Range@Length@h;
     While[h != {},
      nf = Nearest[h -> Automatic];
      num = nf /@ b // Flatten;
      put = Ordering@Total[(h[[num]] - b)^2, {2}];
      fill = num[[put]];
      nondup = Floor@BinarySearch[Range@Length@fill, 1/2, 
         1 - Boole@DuplicateFreeQ@fill[[;; #]] &];
      put = put[[;; nondup]];
      fill = fill[[;; nondup]];
      Sow@Transpose@{nb[[put]], nh[[fill]]};
      b = Delete[b, Transpose@{put}];
      nb = Delete[nb, Transpose@{put}];
      h = Delete[h, Transpose@{fill}];
      nh = Delete[nh, Transpose@{fill}];
      ]
     ]
(* {{8, 24}, {13, 5}, {19, 16}, {23, 10}, {1, 23}, {3, 17}, {5,
   14}, {16, 21}, {17, 3}, {9, 8}, {7, 4}, {18, 11}, {4, 22}, {21, 
  15}, {11, 20}, {2, 6}, {14, 2}, {10, 7}, {15, 9}, {25, 1}, {12, 
  25}, {6, 18}, {22, 19}, {20, 13}, {24, 12}} *)

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], 
  Point[balls], Arrow[{balls[[#]], holes[[#2]]} & @@@ res]}]

enter image description here

Source Link
ybeltukov
  • 43.9k
  • 5
  • 109
  • 215

Minimization of the total Euclidean distance from balls to holes is quite difficult optimization problem (I'm not sure, may be it is a NP-problem). As a start point I propose a simple greedy algorithm:

  • Find the nearest hole for every ball.
  • Put balls to holes starting from the closest ball-hole pair while the corresponding holes are empty
  • Repeat

It is not the best algorithm and may be I will update my post in the future.

n = {5, 5};
holes = N@Tuples@Range@n;
balls = RandomReal[{0, # + 1}, Times @@ n] & /@ n // Transpose;

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], Point[balls]}]

enter image description here

res = Flatten[#, 2] &@ Last@Reap@
    Module[{h = holes, b = balls, nh, nb, nf, num, put, fill, 
      nondup},
     nb = nh = Range@Length@h;
     While[h != {},
      nf = Nearest[h -> Automatic];
      num = nf /@ b // Flatten;
      put = Ordering@Total[(h[[num]] - b)^2, {2}];
      fill = num[[put]];
      nondup = Floor@BinarySearch[Range@Length@fill, 1/2, 
         1 - Boole@DuplicateFreeQ@fill[[;; #]] &];
      put = put[[;; nondup]];
      fill = fill[[;; nondup]];
      Sow@Transpose@{nb[[put]], nh[[fill]]};
      b = Delete[b, Transpose@{put}];
      nb = Delete[nb, Transpose@{put}];
      h = Delete[h, Transpose@{fill}];
      nh = Delete[nh, Transpose@{fill}];
      ]
     ]
(* {{8, 24}, {13, 5}, {19, 16}, {23, 10}, {1, 23}, {3, 17}, {5,
   14}, {16, 21}, {17, 3}, {9, 8}, {7, 4}, {18, 11}, {4, 22}, {21, 
  15}, {11, 20}, {2, 6}, {14, 2}, {10, 7}, {15, 9}, {25, 1}, {12, 
  25}, {6, 18}, {22, 19}, {20, 13}, {24, 12}} *)

Graphics[{PointSize[Large], Point[holes], Red, PointSize[Medium], 
  Point[balls], Arrow[{balls[[#]], holes[[#2]]} & @@@ res]}]

enter image description here