Java 有3个容器(2个满的,1个空的),并试图从中创建x数量
注意:我遇到了下面的问题,我想概括这个问题并实施它,但事实证明这并不容易。这个问题让我发疯。这不是家庭作业问题,只是好奇而已 问题: 共有三个容器,其尺寸分别为10品脱、7品脱和4品脱。7品脱和4品脱的容器开始装满水,但10品脱的容器最初是空的 由于容器上没有标记,您可以将一个容器中的内容物倒入另一个容器中,并在以下条件下停止:Java 有3个容器(2个满的,1个空的),并试图从中创建x数量,java,algorithm,graph,breadth-first-search,Java,Algorithm,Graph,Breadth First Search,注意:我遇到了下面的问题,我想概括这个问题并实施它,但事实证明这并不容易。这个问题让我发疯。这不是家庭作业问题,只是好奇而已 问题: 共有三个容器,其尺寸分别为10品脱、7品脱和4品脱。7品脱和4品脱的容器开始装满水,但10品脱的容器最初是空的 由于容器上没有标记,您可以将一个容器中的内容物倒入另一个容器中,并在以下条件下停止: 源容器为空 目标容器已满 如果你想分离出2品脱的水,你应该采取什么样的步骤 解决方案 回答这个问题很容易,使用where节点包含元组来表示特定状态 我们从初始状态(节
元组来表示特定状态
我们从初始状态(节点)开始,然后创建一个表示可能的下一个状态的节点,并将其连接到初始节点,然后运行以找到最短路径
- 每个状态(或节点)的模式:
- 初始状态或节点:
连接到初始状态(或节点)的节点:
,
,如图所示
一般问题
但是如果我们想把这个问题推广,假设我们有三个容器,它们的大小分别是x,y和z品脱,这样x>=y>=z
y品脱和z品脱容器一开始充满水,但x品脱容器最初是空的
如果你想准确地分离出一品脱水,你应该采取什么样的步骤
提出一个解决泛化版本的方案
这里(,)是到目前为止我的源代码
这里是主类中的两个重要方法。它们根据所有可能的情况填充图形,并确保没有重复节点
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;
}
publicstaticvoidfillgraph(intx,inty,intz){
TupleContainer initialState=新的TupleContainer(x,y,z);
TupleContainer currentState=初始状态;
迭代器it,it_1,it_2,it_3;
Graph.addNode(initialState);
它=addAdjaceEntedgestotuple(currentState).iterator();
while(it.hasNext()){
it_1=addAdjaceEntedgestotuple(it.next()).iterator();
while(it_1.hasNext()){
it_2=addAdjaceEntedgestotuple(it.next()).iterator();
while(it_2.hasNext()){
it_3=addAdjacentEdgesToTuple(it.next()).iterator();
while(it_3.hasNext()){
addAdjaceEntedgestotuple(it.next()).iterator();
}
}
}
}
公共静态集合addAdjacentEdgesToTuple(
元组容器(当前状态){
元组容器;
收集水平;
迭代器;
CollectionLevel=currentState.MixUpContainers();
it=CollectionLevel.iterator();
while(it.hasNext()){
testuplecontainer=it.next();
if(graphContains(容器)!=null)
Graph.addNode(容器);
其他的
TENTUPLECONTAINER=图形内容(TENTUPLECONTAINER);
图.addEdge(当前状态,容器);
}
回收水平;
}
我的问题
我的代码只是将图形填充到深度4,但是我如何设置深度并使其递归运行,或者如何使其在考虑所有可能性之前运行,而不进入无限循环。这个广义问题的算法是什么?Hm…可能有更好的算法,但如果您只是想要任意深度的递归在不进入无休止循环的情况下,您可以使用广度优先搜索,只访问每个节点一次,即如果尚未访问该节点:
public class Test {
public static void main(String[] args) throws Exception {
State initialState = new State(null, 0, 7, 4);
Set<State> reached = new HashSet<>();
Queue<State> pending = new ArrayDeque<>();
pending.add(initialState);
while (!pending.isEmpty()) {
State state = pending.remove();
if (isGoal(state)) {
printPathTo(state);
return;
}
for (State s : state.adjacentStates()) {
if (!reached.contains(s)) {
reached.add(s);
pending.add(s);
}
}
}
System.out.println("There appears to be no solution.");
}
private static boolean isGoal(State state) {
for (int a : state.content) {
if (a == 2) {
return true;
}
}
return false;
}
private static void printPathTo(State state) {
if (state != null) {
printPathTo(state.previous);
System.out.println(state);
}
}
}
class State {
final static int[] capacity = { 10, 7, 4 };
final int[] content;
final State previous;
public State(State previous, int... content) {
this.content = content;
this.previous = previous;
}
Iterable<State> adjacentStates() {
List<State> result = new ArrayList<>();
for (int i = 0; i < content.length; i++) {
for (int j = 0; j < content.length; j++) {
if (i != j) {
int[] newContent = Arrays.copyOf(content, content.length);
int movedQuantity = Math.min(content[i], capacity[j] - content[j]);
newContent[i] -= movedQuantity;
newContent[j] += movedQuantity;
result.add(new State(this, newContent));
}
}
}
return result;
}
@Override
public int hashCode() {
return Arrays.hashCode(content);
}
@Override
public boolean equals(Object obj) {
return Arrays.equals(content, ((State) obj).content);
}
@Override
public String toString() {
return Arrays.toString(content);
}
}
公共类测试{
公共静态void main(字符串[]args)引发异常{
State initialState=新状态(null,0,7,4);
Set reach=新的HashSet();
队列挂起=新的ArrayDeque();
待定。添加(初始状态);
而(!pending.isEmpty()){
State=pending.remove();
如果(目标(状态)){
printPathTo(州);
返回;
}
对于(状态s:State.adjacentStates()){
如果(!reach.contains)){
已达成。添加(s);
待决。添加;
}
}
}
System.out.println(“似乎没有解决方案”);
}
私有静态布尔值isGoal(状态){
for(int a:state.content){
如果(a==2){
返回true;
}
}
返回false;
}
私有静态void printPathTo(状态){
如果(状态!=null){
printPathTo(state.previous);
System.out.println(状态);
}
}
}
阶级国家{
最终静态int[]容量={10,7,4};
最终int[]内容;
最终状态先前;
公共状态(状态先前,int…内容){
this.content=内容;
this.previous=先前;
}
Iterable邻接态(){
列表结果=新建ArrayList();
for(int i=0;i