您的位置:首页 > 编程语言 > Java开发

深度优先搜索例题------Java倒油

2016-05-24 13:28 489 查看
深度搜索倒油:

样题描述:有a、b、c三个油桶;a桶的容量为12斤,现有12斤油;b桶容量为8斤,现有0斤;c桶容量5斤,现有0斤。现一次只能由一个桶向另一个同倒油,问怎样才能倒出6斤油。

[java] view
plain copy

package cn.hncu.search.oil.dfs;  

  

import cn.hncu.search.oil.common.Bucket;  

import cn.hncu.search.oil.common.DumpCase;  

import cn.hncu.search.oil.common.Myset;  

  

public class DumpOilDFS {  

  

    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);  

    }  

    public static void print(DumpCase u,Myset caseSet){  

        Myset set = new Myset();  

        set.add(u);  

        DumpCase d = u.getParent();  

        while(d!=null){  

            set.add(d);  

            d = d.getParent();  

        }  

        System.out.println("------------");  

        Object objs[] = set.getAll();  

        for(int i=objs.length-1; i>=0; i--){  

            DumpCase v = (DumpCase) objs[i];  

            System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);  

        }  

          

    }  

      

    public static void dfs(DumpCase u0, Myset caseSet){  

        //递归鸿沟  

        for(Bucket bucket: u0.getBuckets()){  

            if(bucket.now==6){  

                //System.out.println("find a case");  

                print(u0,caseSet);  

                return;  

            }  

        }  

          

          

        int n = u0.getBuckets().length;//桶的个数  

        DumpCase u = new DumpCase(u0);  

        //用备份节点去搜  

        //遍历所有的DumpCase: 依次让桶i向j倒  

        for(int i=0;i<n;i++){  

            for(int j=0;j<n;j++){  

                //自己不能给自己倒  

                if(i==j){  

                    continue;  

                }  

                  

                //算出桶i给j倒时,能倒多少-->canDump  

                int canDump = u.getBuckets()[i].canOut();  

                if(u.getBuckets()[i].canOut()>u.getBuckets()[j].canIn()){  

                    canDump = u.getBuckets()[j].canIn();  

                }  

                //倒油  

                u.getBuckets()[i].out(canDump);  

                u.getBuckets()[j].in(canDump);  

                  

                //System.out.println(u.getBuckets()[0].now+","+u.getBuckets()[1].now+","+u.getBuckets()[2].now);  

                //判断该情况是否已经出现过了//如果存在,要还原(把油倒回去)  

                if(caseSet.contains(u)){  

                    //把油还回去  

                    u.getBuckets()[i].in(canDump);  

                    u.getBuckets()[j].out(canDump);  

                    continue;  

                }  

                  

                //经过上面的哨兵,说明这样倒可以  

                DumpCase v = new DumpCase(u);  

                v.setParent(u0);  

                caseSet.add(v);  

                //System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);  

                dfs(v,caseSet);  

                  

                //再倒回去,以重新进行下一个邻居的遍历  

                u.getBuckets()[i].in(canDump);  

                u.getBuckets()[j].out(canDump);  

                  

            }  

        }  

    }  

}  

[java] view
plain copy

package cn.hncu.search.oil.common;  

  

public class Bucket {  

    public int max;  

    public int now;  

  

    public Bucket(int max, int now) {  

        this.max = max;  

        this.now = now;  

    }  

    public void in(int a){  

        now += a;  

    }  

    public void out(int a){  

        now -=a;  

    }  

    public int canIn(){  

        return max-now;  

    }  

    public int canOut(){  

        return now;  

    }  

    @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;  

    }  

      

}  

[java] view
plain copy

package cn.hncu.search.oil.common;  

  

import java.util.Arrays;  

  

public class DumpCase {  

    Bucket buckets[];  

    DumpCase parent = null;  

  

    public DumpCase() {  

    }  

      

    public DumpCase(Bucket buckets[]) {  

        this.buckets = buckets;  

    }  

      

    //必须要进行深拷贝  

    public DumpCase(DumpCase u) {  

        this.buckets = new Bucket[ u.getBuckets().length ];  

        for(int i=0; i<u.getBuckets().length;i++){  

            buckets[i] = new Bucket(0,0);  

            buckets[i].max = u.getBuckets()[i].max;  

            buckets[i].now = u.getBuckets()[i].now;  

        }  

    }  

  

    public Bucket[] getBuckets() {  

        return buckets;  

    }  

  

    public DumpCase getParent() {  

        return parent;  

    }  

  

    public void setParent(DumpCase parent) {  

        this.parent = parent;  

    }  

  

    @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;  

    }  

      

    //※1 用“特征串”来代表整个对象,如果特征串相等,则表示是相等的对象。这样在比较对象时,性能就提高了  

    public String toString(){  

        return "A="+buckets[0].now+",B="+buckets[1].now+",C="+buckets[2].now;  

    }  

      

}  

[java] view
plain copy

package cn.hncu.search.oil.common;  

  

public class Myset {  

    private Object[] objs= new Object[0];  

    public boolean contains(Object obj){  

        for(Object tmp: objs){  

            if(tmp.equals(obj)){  

                return true;  

            }  

        }  

        return false;  

    }  

    public boolean add(Object obj){  

        if(contains(obj)){  

            return false;  

        }  

        Object[] tempObjs = new Object[objs.length+1];  

        System.arraycopy(objs, 0, tempObjs, 0, objs.length);  

        tempObjs[objs.length] = obj;  

        objs = tempObjs;  

        return true;  

    }  

    public Object[] getAll(){  

        return objs;  

    }  

    public int size(){  

        return objs.length;  

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息