简体   繁体   中英

Algorithm to move balls from one set of buckets to another set in least amount of moves given a machine that can move unlimited balls in one move

One of my friends proposed a problem where you have n number of buckets (a, b, c, ..., n), each with a certain percentage of your total balls. You are then given a breakdown of how many balls each bucket should have by the end of the problem. You are also supplied a machine that, in one move, can move unlimited balls from a singular bucket to another singular bucket (ex. 10 balls from bucket A to bucket C). What algorithm would you use to ensure you always have the least number of moves possible?

I got stumped by this. It looks like it could be solved using an extension of Euclid's algorithm, but I'm altogether unsure as to how I would solve this. I tested the obvious answer of trying to match the 2 largest/perfect problem buckets with each other but that doesn't work. Any pointers would be helpful.

I've deleted my previous answer. Have you considered the subset sum problem? I'm not sure if it will find the optimal solution for the overall problem, but here is the idea.

For each bucket, let the difference = (target number of balls) - (given number of balls). Let P be a set of positive differences and N be a set of absolute values of negative differences.
Choose the next maximum number from the two sets, and look for a minimum subset sum in the opposite set. If the subset is found, move the balls. Otherwise, look for the subset sum for the next maximum number from the sets.

After finishing looking for subsets, consider the remaining buckets. Move the balls between two of the remaining buckets from opposite sets. This will create a new difference for one of the buckets. It is possible that a new matching subset sum can be formed with the new difference. Search for the subset sum again using that newly formed difference. Repeat until all of the buckets have the target number of balls.

I'm not sure if always considering the largest buckets guarantees optimality. Let us know if you find the correct solution!

Use A* on the graph of possible moves with the heuristic function: number of buckets different from their goal bucket divided by two. That is b/2 where b is the number of buckets which have the wrong amount in them.

A* is often thought of as a pathfinding algorithm for like routing units in an game, but it works on any graph that you can find an heuristic that never overestimates the distance to the target node. Most importantly, A* armed with such a heuristic will always find the shortest path. Borrowing from game theory, we can think of a graph, nodes connected by links, where each node is a possible distribution of balls among the buckets and each link represents a legal move the machine can make. Your starting node is the starting distribution of balls. Your target node is the target distribution of balls.

With this graph we could apply a breath-first search and the wait until we happen to visit the target node. This would give us a shortest set of moves from start distribution to target distribution, since it is a breath-first search. (This is more or less equivalent to Dijkstra's algorithm in this case because each move has the same cost (length) of 1 move)

However, we can do better. A* searches through a graph using a heuristic. Specifically, it is like the breath-first search except instead of next visiting an un-visited node nearest to the starting node, A* next visits an un-visited node which minimizes g(n) + h(n) where g(n) is the length from the unvisited node, n , to the starting node and h(n) is an heuristic for the distance from the unvisited node, n , to the goal. This means we spend less computational time hunting for the optimal path by going "away" from the goal as we check the obvious path to goal first. It has been mathematically proven that A* will give you the optimal path from your starting node to the goal node if you can find a heuristic that is admissible, meaning a heuristic that never overestimates the distance to goal. For example, in a video game, the length of a walkable path between two points is always greater or equal to the by-the-crow-flies distance. In spite of our graph not being a graph that represents physical space, we can still find an admissible heuristic.

A move can at best make 2 buckets have the correct number of balls, as a move can only effect two buckets at most. Thus, for example, if we count our buckets and see that 4 buckets have the wrong about of balls in them, then we know that at least 2 moves will be required. Quite possible more, but it can't be less than 2.

Lets make our heuristic be "the number of buckets which have the wrong number of balls divided by 2".

Our heuristic doesn't overestimate the number of moves required to get desired number of balls, since even the best kind of move where you match up happy pairs can happen for every move you only tie our heuristic. Our heuristic underestimates moves quite often but that is okay, the computation will just take longer but it won't get the wrong result, and the result plan for moves will still the shortest possible. Thus, our heuristic is admissible, meaning that it never overestimates the number of moves.

Therefore, A* with a heuristic of "the number of buckets which have the wrong number of balls divided by 2" will always find the shortest number of moves to reach the distribution.

Perhaps a better heuristic can be found, if so, then the search will go faster. This was merely the first heuristic I thought of.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM