问题描述:
三只水桶等分水问题
有一个容积为8升的水桶里装满了水,另外还有一个容积为3升的空桶和一个容积为5升的空桶,
如何利用这两个空桶等分8升水?
附加条件是三个水桶都没有体积刻度,也不能使用其它辅助容器。
学习王晓华老师的《算法的乐趣》一书中第五章之后,用Java重写并实现这一功能。
该文章是在学习完该章之后的一个学习总结,以供自己复习使用。
由于现在刚开始学习Java,为了熟悉Java的变成规范,因此,用Java实现这一功能。
import java.util.LinkedList;
import java.util.ListIterator;
/**
* 三只水桶等分水问题
* 有一个容积为8升的水桶里装满了水,另外还有一个容积为3升的空桶和一个容积为5升的空桶,
* 如何利用这两个空桶等分8升水?
* 附加条件是三个水桶都没有体积刻度,也不能使用其它辅助容器。
*
*/
public class QuestionOfDumpWaterFromBuckets {
static int BUCKETS_COUNT = 3; //定义水桶的个数
static int BUCKETS_CAPACITY[] = new int[]{8, 5, 3}; //定义三个水桶所能容纳的最大的水的含量
static int BUCKET_INIT_STATE[] = new int[]{8, 0, 0}; //定义起始时,三个水桶初始的状态
static int BUCKET_FINAL_STATE[] = new int[]{4, 4, 0}; //定义三个水桶最终的状态
public static class MyException extends Exception { //自定义异常类,继承Exception类
public MyException(String msg) { //构造方法接收异常信息
super(msg); //调用父类中的构造方法
}
}
/**
* 倒水动作的模型
*/
public static class ActionState {
int from;
int to;
int water;
}
/**
* 定义该问题的状态模型,状态模型一方面要能描述各个水桶的静止状态,
* 另一面要能描述水桶是如何从上一个状态转换到当前状态的,即倒水这一动作。
*/
public static class BucketState {
int bucketState[] = new int[BUCKETS_COUNT]; //用来表示当前各个桶的状态
ActionState currentAction = new ActionState(); //当前的倒水动作,是的各个桶的状态从上个状态达到当前的状态
/**
* 初始化状态模型的时候,要设置各个桶的静止状态(bucker_s[]),并且设置与这个状态相对应的倒水动作。
* 初始时,假设这个倒水动作是从一个标号为(-1)的桶中将8升水倒入到标号为(0)的桶中。
*
* @param bucket_s 表示初始时各个桶的静止状态时所容纳的水
*/
public BucketState(int bucket_s[]) {
setBucketState(bucket_s);
setActionState(8, -1, 0);
}
/**
* 初始化状态模型的时候,要设置各个桶的静止状态为初始状态,并且设置与这个状态相对应的倒水动作。
* 初始时,假设这个倒水动作是从一个标号为(-1)的桶中将8升水倒入到标号为(0)的桶中。
*/
public BucketState() {
setBucketState(BUCKET_INIT_STATE);
setActionState(8, -1, 0);
}
/**
* 初始化状态模型,将一个状态赋值给this
* @param state
*/
public BucketState(BucketState state) {
setBucketState(state.bucketState);
setActionState(state.currentAction.water, state.currentAction.from, state.currentAction.to);
}
/**
* 设置各个桶的静止状态
*
* @param bucket_s 设置桶的静止状态时候的水的容量
*/
public void setBucketState(int bucket_s[]) {
for (int i = 0; i < BUCKETS_COUNT; i++) {
this.bucketState[i] = bucket_s[i];
}
}
/**
* 设置桶达到静止状态时所对应的倒水动作
*
* @param water
* @param from
* @param to
*/
public void setActionState(int water, int from, int to) {
this.currentAction.water = water;
this.currentAction.from = from;
this.currentAction.to = to;
}
/**
* 判断编号为bucketIndex的桶是不是空的,若为空返回true,否则返回false
* @param bucketIndex
* @return
*/
public Boolean isBucketEmpty(int bucketIndex) {
if (bucketIndex < 0 || bucketIndex >= BUCKETS_COUNT) {
try {
throw new MyException("桶的编号是错误的!!");
} catch (Exception e) {
System.out.println(e);
}
}
if (this.bucketState[bucketIndex] > 0) {
return false;
} else {
return true;
}
}
/**
* 判断编号为bucketIndex的桶是不是满的,若为满返回true,否则返回false
* @param bucketIndex
* @return
*/
public Boolean isBucketFull(int bucketIndex) {
if (bucketIndex < 0 || bucketIndex >= BUCKETS_COUNT) {
try {
throw new MyException("桶的编号是错误的!!");
} catch (Exception e) {
System.out.println(e);
}
}
if (this.bucketState[bucketIndex] >= BUCKETS_CAPACITY[bucketIndex]) {
return true;
} else {
return false;
}
}
/**
* 判断state与this这两个状态模型的三个水桶的静止状态是不是一样,若一样返回true,否则返回false
* @param state
* @return
*/
public Boolean isSameState(BucketState state) {
for (int i = 0; i < BUCKETS_COUNT; ++i) {
if (this.bucketState[i] != state.bucketState[i])
return false;
}
return true;
}
/**
* 打印this状态模型的倒水动作,与三个水桶的静止状态
*/
public void printState() {
System.out.println("Dump " + this.currentAction.water + " water from " + (this.currentAction.from + 1) + " to " + (this.currentAction.to + 1));
System.out.print("buckets water states is : ");
printArry(this.bucketState);
}
/**
* 判断this状态是不是最终的状态,若是则返回true,否则返回false
* @return
*/
public Boolean isFinalState(){
return this.isSameState(new BucketState(BUCKET_FINAL_STATE));
}
/**
* 剪枝操作,判断这个倒水动作能不能进行,from桶不能与to桶一致,from桶不为空,to桶不满,
* 若是这样返回true,否则返回false
* @param from
* @param to
* @return
*/
public Boolean canTakeDumpActionState(int from,int to){
if (from < 0 || from >= BUCKETS_COUNT) {
try {
throw new MyException("from桶的编号是错误的!!");
} catch (Exception e) {
System.out.println(e);
}
}
if (to < 0 || to >= BUCKETS_COUNT) {
try {
throw new MyException("to桶的编号是错误的!!");
} catch (Exception e) {
System.out.println(e);
}
}
if( (from != to) && !this.isBucketEmpty(from) && !this.isBucketFull(to) )
{
return true;
}
return false;
}
/**
* 从from桶倒水到to桶,若是合法的倒水动作,返回true,否则返回false
* 若倒水动作合法,则用next记录倒水之后的状态。
* @param from
* @param to
* @param next
* @return
*/
public Boolean dumpWater(int from,int to,BucketState next){
next.setBucketState(this.bucketState);
int dump_water = BUCKETS_CAPACITY[to] - next.bucketState[to]; //to桶中可以容纳的水
if(next.bucketState[from] >= dump_water) //如果from桶中的水的容量大于等于to桶可以容纳的水,to桶加上dump_water,from桶减去dump_water
{
next.bucketState[to] += dump_water;
next.bucketState[from] -= dump_water;
}
else //如果from桶中的水的容量小于to桶可以容纳的水,to桶加上from桶中的水的容量,dump_water等于from桶中的水,from桶中的水置零。
{
next.bucketState[to] += next.bucketState[from];
dump_water = next.bucketState[from];
next.bucketState[from] = 0;
}
if(dump_water > 0) /*是一个有效的倒水动作?*/
{
next.setActionState(dump_water, from, to);
return true;
}
return false;
}
}
/**
* 避免循环的出现,判断状态state是否已经出现并记录在了states中。若state存在于states中,返回true,否则返回false
* @param states
* @param state
* @return
*/
public static Boolean isProcessedState(LinkedList<BucketState> states,BucketState state){
ListIterator<BucketState> itr= states.listIterator();
while (itr.hasNext()){
if(itr.next().isSameState(state)) {
return true;
}
}
return false;
}
static int count=0; //用来记录以供有多少种方法
/**
* 当最终状态出现之后,将states打印出来
* @param states
*/
public static void printResult(LinkedList<BucketState> states){
System.out.println("---------find result "+(++count)+"------------");
ListIterator<BucketState> itr= states.listIterator();
while (itr.hasNext()){
itr.next().printState();
}
}
/**
*
* @param states
* @param current
* @param from
* @param to
*/
public static void searchStateOnAction(LinkedList<BucketState> states,BucketState current,int from,int to){
if(current.canTakeDumpActionState(from, to))
{
BucketState next=new BucketState();
/*从from到to倒水,如果成功,返回倒水后的状态*/
Boolean bDump = current.dumpWater(from, to, next);
if(bDump && !isProcessedState(states, next))
{
states.addLast(next);
searchState(states);
states.removeLast();
}
}
}
/**
*
* @param states
*/
public static void searchState(LinkedList<BucketState> states){
BucketState current = states.getLast(); /*每次都从当前状态开始*/
if(current.isFinalState()) //判断当前状态是不是最终状态,是的话,打印整个states
{
printResult(states);
return;
}
/*使用两重循环排列组合6种倒水状态*/
for(int j = 0; j < BUCKETS_COUNT; ++j)
{
for(int i = 0; i < BUCKETS_COUNT; ++i)
{
searchStateOnAction(states, current, i, j);
}
}
}
/**
* 打印int a[]的类型的数组
* @param a
*/
public static void printArry(int a[]) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
LinkedList<BucketState> states = new LinkedList<>();
BucketState init=new BucketState();
states.addLast(init); //将初始的状态插入到LinkedList states的最后端
searchState(states); //调用状态树搜索算法
System.out.println("---------------after--------------");
//在穷举完状态树之后,状态树的大小应该为1,并且为初始时的状态。
System.out.println(states.size());
printArry(states.getLast().bucketState);
}
}
输出结果为:
---------find result 1------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 1 to 3
buckets water states is : 0 5 3
Dump 5 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 2------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 2 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 3------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 1 to 3
buckets water states is : 0 5 3
Dump 5 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 4------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 4 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 5------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 6------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 1 water from 1 to 2
buckets water states is : 0 5 3
Dump 5 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 7------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 1 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 8------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 5 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 1 to 2
buckets water states is : 0 5 3
Dump 5 water from 2 to 1
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 9------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 5 water from 1 to 2
buckets water states is : 0 5 3
Dump 3 water from 3 to 1
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 10------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 2 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 11------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 1 to 2
buckets water states is : 0 5 3
Dump 3 water from 3 to 1
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 12------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 4 water from 1 to 2
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 13------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 4 water from 1 to 2
buckets water states is : 0 5 3
Dump 3 water from 3 to 1
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 14------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 5 water from 2 to 1
buckets water states is : 7 0 1
Dump 1 water from 3 to 2
buckets water states is : 7 1 0
Dump 3 water from 1 to 3
buckets water states is : 4 1 3
Dump 3 water from 3 to 2
buckets water states is : 4 4 0
---------find result 15------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 1 water from 3 to 1
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------find result 16------------
Dump 8 water from 0 to 1
buckets water states is : 8 0 0
Dump 3 water from 1 to 3
buckets water states is : 5 0 3
Dump 3 water from 3 to 2
buckets water states is : 5 3 0
Dump 3 water from 1 to 3
buckets water states is : 2 3 3
Dump 2 water from 3 to 2
buckets water states is : 2 5 1
Dump 2 water from 1 to 3
buckets water states is : 0 5 3
Dump 3 water from 3 to 1
buckets water states is : 3 5 0
Dump 3 water from 2 to 3
buckets water states is : 3 2 3
Dump 3 water from 3 to 1
buckets water states is : 6 2 0
Dump 2 water from 2 to 3
buckets water states is : 6 0 2
Dump 5 water from 1 to 2
buckets water states is : 1 5 2
Dump 1 water from 2 to 3
buckets water states is : 1 4 3
Dump 3 water from 3 to 1
buckets water states is : 4 4 0
---------------after--------------
1
8 0 0
Process finished with exit code 0
一共有16种结果,可以解决三个水桶等分水问题