倒油问题

倒油问题

有一位厨师要从12斤油(A桶)倒出6斤油但现在手里只有8斤和5斤的桶,怎么取出6斤。

Bucket类

package 搜索.oilTest.common;

public class Bucket {
    public int max;//油桶最大容量
    public int now;//油桶中的油有多少

    public Bucket(int max, int now) {
        this.max = max;
        this.now = now;
    }


    public int canIn(){//油桶能倒进多少油
        return max-now;
    }

    public int canOut(){//油桶能倒出多少油
        return now;
    }

    public void in(int a){//倒进a
        now+=a;
    }

    public void out(int a){//倒出b
        now-=a;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + max;
        result = prime * result + now;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Bucket other = (Bucket) obj;
        if (max != other.max)
            return false;
        if (now != other.now)
            return false;
        return true;
    }



}

DumpCase类

package 搜索.oilTest.common;

import java.util.Arrays;



public class DumpCase {
    public Bucket[] buckets = null;
    public DumpCase parents = null;

    public DumpCase(Bucket[] buckets) {
        this.buckets = buckets;
    }

    public DumpCase(DumpCase u){
        buckets=new Bucket[u.buckets.length];
        for(int i=0;i<buckets.length;i++){
            buckets[i]=new Bucket(0,0);
            buckets[i].max=u.buckets[i].max;
            buckets[i].now=u.buckets[i].now;
        }
    }
    @Override
    public String toString() {
        return "A=" +buckets[0].now+ " B="+buckets[1].now+ " C="+buckets[2].now;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(buckets);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DumpCase other = (DumpCase) obj;
        if (!Arrays.equals(buckets, other.buckets))
            return false;
        return true;
    }

}

MySet自定义集合类

package 搜索.oilTest.common;

public class MySet {
     Object[] objs=new Object[0];//不能用static 不然数据会串扰
     public boolean add(Object obj){
         if(contain(obj)){
             return false;
         }
         Object[] temp=new Object[objs.length+1];
         System.arraycopy(objs, 0, temp, 0, objs.length);
         temp[objs.length]=obj;
         objs=temp;
         return true;
     }
    public boolean contain(Object obj) {
        for(Object o:objs){
            if(o.equals(obj)){
                return true;
            }
        }
        return false;
    }
    public Object[] getAll(){
        return objs;
    }
    public int size(){
        return objs.length;
    }
}

深搜倒油

package 搜索.oilTest.dfs;


import 搜索.oilTest.common.Bucket;
import 搜索.oilTest.common.DumpCase;
import 搜索.oilTest.common.MySet;

public class DumpOilDfs1 {
    public static void main(String[] args) {
        Bucket[] buckets = new Bucket[3];
        buckets[0] = new Bucket(12, 12);
        buckets[1] = new Bucket(8, 0);
        buckets[2] = new Bucket(5, 0);

        DumpCase u = new DumpCase(buckets);
        MySet caseSet = new MySet();
        caseSet.add(u);

        dfs(u, caseSet);
    }

    private static void dfs(DumpCase u, MySet caseSet) {
        // 鸿沟
        if (u.buckets[0].now == 6 || u.buckets[1].now == 6) {
            // System.out.println(u);
            print(u, caseSet);
            return;
        }
        // 把油桶i中的油倒向j
        // DumpCase temp=u;不能这样做 ,会发生捆绑
        DumpCase temp = new DumpCase(u);
        for (int i = 0; i < temp.buckets.length; i++) {
            for (int j = 0; j < temp.buckets.length; j++) {
                if (i == j) {
                    continue;
                }
                // 判断能倒多少油
                int icanDump = temp.buckets[i].canOut();
                if (icanDump > temp.buckets[j].canIn()) {
                    icanDump = temp.buckets[j].canIn();
                }
                // 倒油
                temp.buckets[i].out(icanDump);
                temp.buckets[j].in(icanDump);
                if (caseSet.contain(temp)) {
                    temp.buckets[j].out(icanDump);
                    temp.buckets[i].in(icanDump);
                    continue;
                }
                DumpCase v = new DumpCase(temp);
                v.parents = u;
                caseSet.add(v);
                dfs(v, caseSet);
                // 还原现场
                temp.buckets[i].in(icanDump);
                temp.buckets[j].out(icanDump);
                temp.parents = null;// 可以省略

            }
        }

    }

    private static void print(DumpCase u, MySet caseSet) {
        MySet set = new MySet();
        set.add(u);
        DumpCase d = u.parents;
        while(d!=null){
            set.add(d);
            d = d.parents;
        }
        System.out.println("--------------");
        Object objs[] = set.getAll();
        for(Object obj: objs){
            System.out.println(obj);
        }
    }
}

广搜倒油

package 搜索.oilTest.bfs;

import csx.myset.v1.MySet;
import 搜索.oilTest.common.Bucket;
import 搜索.oilTest.common.DumpCase;

public class DumpOilbfs {
    public static void main(String[] args) {
        Bucket[] buckets = new Bucket[3];
        buckets[0] = new Bucket(12, 12);
        buckets[1] = new Bucket(8, 0);
        buckets[2] = new Bucket(5, 0);

        DumpCase u = new DumpCase(buckets);
        MySet caseSet = new MySet();
        caseSet.add(u);
        CaseQue que = new CaseQue();
        que.enque(u);
        bfs(que, caseSet);
    }

    private static void bfs(CaseQue que, MySet caseSet) {
        while (!que.isEmpty()) {
            DumpCase u = que.deque();
            // 满足条件 输出结果
            if (u.buckets[0].now == 6 || u.buckets[1].now == 6) {
                print(u, caseSet);
                continue;
            }
            DumpCase temp = new DumpCase(u);
            for (int i = 0; i < temp.buckets.length; i++) {
                for (int j = 0; j < temp.buckets.length; j++) {
                    // 不能自己向自己倒油
                    if (i == j) {
                        continue;
                    }
                    // 要倒多少油
                    int iCanDump = temp.buckets[i].canOut();
                    if (iCanDump > temp.buckets[j].canIn()) {
                        iCanDump = temp.buckets[j].canIn();
                    }
                    // 等于0不用倒
                    if (iCanDump == 0) {
                        continue;
                    }
                    // 倒油
                    temp.buckets[i].out(iCanDump);
                    temp.buckets[j].in(iCanDump);
                    // 判断是否已经存在
                    if (caseSet.contains(temp)) {
                        temp.buckets[j].out(iCanDump);
                        temp.buckets[i].in(iCanDump);
                        continue;
                    }

                    // 到这里,说明这种倒法是可以的,而且之前没出现过,可以从此结点搜索下去
                    // 对这种情况进行记录,注意要拷贝一份新的存入集体,否则会和下一次循环发现捆绑
                    DumpCase v = new DumpCase(temp);
                    v.parents = u;
                    caseSet.add(v); // 记录到已经搜索的结点集合当中
                    que.enque(v);// 加入到广搜队列当中

                    // 必须还原,以便从该结点继续尝试其它路径
                    temp.buckets[j].out(iCanDump);
                    temp.buckets[i].in(iCanDump);

                }
            }
        }

    }

    private static void print(DumpCase u, MySet caseSet) {
        MySet set = new MySet();
        set.add(u);
        DumpCase d = u.parents;
        while (d != null) {
            set.add(d);
            d = d.parents;
        }
        System.out.println("-----------");
        Object objs[] = set.getAll();
        for (int i = objs.length - 1; i >= 0; i--) {
            System.out.println(objs[i]);
        }
    }
}

class CaseQue {
    DumpCase[] que = new DumpCase[100];
    int end = 0;

    public int enque(DumpCase u) {
        que[end++] = u;
        return end;
    }

    public DumpCase deque() {
        if (isEmpty()) {
            return null;
        }
        DumpCase u = que[0];
        if (end > 1) {
            for (int i = 0; i < end; i++) {
                que[i] = que[i + 1];
            }
        }
        end--;
        return u;
    }

    public boolean isEmpty() {
        if (end == 0) {
            return true;
        } else {
            return false;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值