Note. I came across the question below, and I wanted to generalize the problem and implement it, but it turns out that this is not easy. This question makes me go crazy. This is not a matter of homework, just curiosity.
Question
There are three containers that are 10 pints, 7 pints and 4 pints respectively. Containers with 7 pints and 4 pints start with water, but a container of 10 pints is initially empty.
Since there are no labels on the containers, you can pour the contents of one container into another and stop under the following conditions:
- source container is empty
- destination container is full.
What sequence of actions should you do if you want to isolate exactly 2 pints of water?
Source: page 102, question 3.8
Decision
The answer to this question is easy using a directional graph structure , where the nodes contain tuples
to represent a specific state.
We start from the initial state (node), and then create a node representing the possible next state, and connect it to the initial node, and then run BFS to find the shortest path.
The structure of each state (or node): <10-pint container, 7-pint container, 2-pint container>
Initial state or node: <0, 7, 4>
.
The nodes connected to the initial state (or node): <7, 0, 4>
, <4, 7, 0>
, as you can see in the picture.

Generalized question
But suppose that if you want to generalize the problem, suppose that we have three containers whose dimensions are x, y and z pints, respectively, that x >= y >= z
.
The y-pint and z-pint containers start with water, but the x-pint container is initially empty.
What sequence of actions should you do if you want to isolate precisely pints of water?
We offer a solution for the generalized version
Here ( DropBox , GitHub ) is my source code.
Here are two important methods in the main class. They populate a graph based on all the features, and it also ensures that there is no duplicate node.
public static void fillGraph(int x, int y, int z) { TupleContainer initialState = new TupleContainer(x, y, z); TupleContainer currentState = initialState; Iterator<TupleContainer> it, it_1, it_2, it_3; Graph.addNode(initialState); it = addAdjacentEdgesToTuple(currentState).iterator(); while (it.hasNext()) { it_1 = addAdjacentEdgesToTuple(it.next()).iterator(); while (it_1.hasNext()) { it_2 = addAdjacentEdgesToTuple(it.next()).iterator(); while (it_2.hasNext()) { it_3 = addAdjacentEdgesToTuple(it.next()).iterator(); while (it_3.hasNext()) { addAdjacentEdgesToTuple(it.next()).iterator(); } } } } public static Collection<TupleContainer> addAdjacentEdgesToTuple( TupleContainer currentState) { TupleContainer tempTupleContainer; Collection<TupleContainer> CollectionLevel; Iterator<TupleContainer> it; CollectionLevel = currentState.MixUpContainers(); it = CollectionLevel.iterator(); while (it.hasNext()) { tempTupleContainer = it.next(); if (graphContains(tempTupleContainer) != null) Graph.addNode(tempTupleContainer); else tempTupleContainer = graphContains(tempTupleContainer); Graph.addEdge(currentState, tempTupleContainer); } return CollectionLevel; }
My question
My code simply fills the chart to a depth of 4, but how can I set the depth and make it work recursively or how to make it work until all the possibilities are considered without going into an infinite loop. What is the algorithm for this generalized question?