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

深度搜索倒油:

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

[java]  view plain  copy
  1. package cn.hncu.search.oil.dfs;  
  2.   
  3. import cn.hncu.search.oil.common.Bucket;  
  4. import cn.hncu.search.oil.common.DumpCase;  
  5. import cn.hncu.search.oil.common.Myset;  
  6.   
  7. public class DumpOilDFS {  
  8.   
  9.     public static void main(String[] args) {  
  10.         Bucket buckets[] = new Bucket[3];  
  11.         buckets[0] = new Bucket(1212);  
  12.         buckets[1] = new Bucket(80);  
  13.         buckets[2] = new Bucket(50);  
  14.         DumpCase u = new DumpCase(buckets);  
  15.           
  16.         Myset caseSet = new Myset();  
  17.         caseSet.add(u);  
  18.         dfs(u,caseSet);  
  19.     }  
  20.     public static void print(DumpCase u,Myset caseSet){  
  21.         Myset set = new Myset();  
  22.         set.add(u);  
  23.         DumpCase d = u.getParent();  
  24.         while(d!=null){  
  25.             set.add(d);  
  26.             d = d.getParent();  
  27.         }  
  28.         System.out.println("------------");  
  29.         Object objs[] = set.getAll();  
  30.         for(int i=objs.length-1; i>=0; i--){  
  31.             DumpCase v = (DumpCase) objs[i];  
  32.             System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);  
  33.         }  
  34.           
  35.     }  
  36.       
  37.     public static void dfs(DumpCase u0, Myset caseSet){  
  38.         //递归鸿沟  
  39.         for(Bucket bucket: u0.getBuckets()){  
  40.             if(bucket.now==6){  
  41.                 //System.out.println("find a case");  
  42.                 print(u0,caseSet);  
  43.                 return;  
  44.             }  
  45.         }  
  46.           
  47.           
  48.         int n = u0.getBuckets().length;//桶的个数  
  49.         DumpCase u = new DumpCase(u0);  
  50.         //用备份节点去搜  
  51.         //遍历所有的DumpCase: 依次让桶i向j倒  
  52.         for(int i=0;i<n;i++){  
  53.             for(int j=0;j<n;j++){  
  54.                 //自己不能给自己倒  
  55.                 if(i==j){  
  56.                     continue;  
  57.                 }  
  58.                   
  59.                 //算出桶i给j倒时,能倒多少-->canDump  
  60.                 int canDump = u.getBuckets()[i].canOut();  
  61.                 if(u.getBuckets()[i].canOut()>u.getBuckets()[j].canIn()){  
  62.                     canDump = u.getBuckets()[j].canIn();  
  63.                 }  
  64.                 //倒油  
  65.                 u.getBuckets()[i].out(canDump);  
  66.                 u.getBuckets()[j].in(canDump);  
  67.                   
  68.                 //System.out.println(u.getBuckets()[0].now+","+u.getBuckets()[1].now+","+u.getBuckets()[2].now);  
  69.                 //判断该情况是否已经出现过了//如果存在,要还原(把油倒回去)  
  70.                 if(caseSet.contains(u)){  
  71.                     //把油还回去  
  72.                     u.getBuckets()[i].in(canDump);  
  73.                     u.getBuckets()[j].out(canDump);  
  74.                     continue;  
  75.                 }  
  76.                   
  77.                 //经过上面的哨兵,说明这样倒可以  
  78.                 DumpCase v = new DumpCase(u);  
  79.                 v.setParent(u0);  
  80.                 caseSet.add(v);  
  81.                 //System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);  
  82.                 dfs(v,caseSet);  
  83.                   
  84.                 //再倒回去,以重新进行下一个邻居的遍历  
  85.                 u.getBuckets()[i].in(canDump);  
  86.                 u.getBuckets()[j].out(canDump);  
  87.                   
  88.             }  
  89.         }  
  90.     }  
  91. }  

[java]  view plain  copy
  1. package cn.hncu.search.oil.common;  
  2.   
  3. public class Bucket {  
  4.     public int max;  
  5.     public int now;  
  6.   
  7.     public Bucket(int max, int now) {  
  8.         this.max = max;  
  9.         this.now = now;  
  10.     }  
  11.     public void in(int a){  
  12.         now += a;  
  13.     }  
  14.     public void out(int a){  
  15.         now -=a;  
  16.     }  
  17.     public int canIn(){  
  18.         return max-now;  
  19.     }  
  20.     public int canOut(){  
  21.         return now;  
  22.     }  
  23.     @Override  
  24.     public int hashCode() {  
  25.         final int prime = 31;  
  26.         int result = 1;  
  27.         result = prime * result + max;  
  28.         result = prime * result + now;  
  29.         return result;  
  30.     }  
  31.     @Override  
  32.     public boolean equals(Object obj) {  
  33.         if (this == obj)  
  34.             return true;  
  35.         if (obj == null)  
  36.             return false;  
  37.         if (getClass() != obj.getClass())  
  38.             return false;  
  39.         Bucket other = (Bucket) obj;  
  40.         if (max != other.max)  
  41.             return false;  
  42.         if (now != other.now)  
  43.             return false;  
  44.         return true;  
  45.     }  
  46.       
  47. }  

[java]  view plain  copy
  1. package cn.hncu.search.oil.common;  
  2.   
  3. import java.util.Arrays;  
  4.   
  5. public class DumpCase {  
  6.     Bucket buckets[];  
  7.     DumpCase parent = null;  
  8.   
  9.     public DumpCase() {  
  10.     }  
  11.       
  12.     public DumpCase(Bucket buckets[]) {  
  13.         this.buckets = buckets;  
  14.     }  
  15.       
  16.     //必须要进行深拷贝  
  17.     public DumpCase(DumpCase u) {  
  18.         this.buckets = new Bucket[ u.getBuckets().length ];  
  19.         for(int i=0; i<u.getBuckets().length;i++){  
  20.             buckets[i] = new Bucket(0,0);  
  21.             buckets[i].max = u.getBuckets()[i].max;  
  22.             buckets[i].now = u.getBuckets()[i].now;  
  23.         }  
  24.     }  
  25.   
  26.     public Bucket[] getBuckets() {  
  27.         return buckets;  
  28.     }  
  29.   
  30.     public DumpCase getParent() {  
  31.         return parent;  
  32.     }  
  33.   
  34.     public void setParent(DumpCase parent) {  
  35.         this.parent = parent;  
  36.     }  
  37.   
  38.     @Override  
  39.     public int hashCode() {  
  40.         final int prime = 31;  
  41.         int result = 1;  
  42.         result = prime * result + Arrays.hashCode(buckets);  
  43.         return result;  
  44.     }  
  45.   
  46.     @Override  
  47.     public boolean equals(Object obj) {  
  48.         if (this == obj)  
  49.             return true;  
  50.         if (obj == null)  
  51.             return false;  
  52.         if (getClass() != obj.getClass())  
  53.             return false;  
  54.         DumpCase other = (DumpCase) obj;  
  55.         if (!Arrays.equals(buckets, other.buckets))  
  56.             return false;  
  57.         return true;  
  58.     }  
  59.       
  60.     //※1 用“特征串”来代表整个对象,如果特征串相等,则表示是相等的对象。这样在比较对象时,性能就提高了  
  61.     public String toString(){  
  62.         return "A="+buckets[0].now+",B="+buckets[1].now+",C="+buckets[2].now;  
  63.     }  
  64.       
  65. }  

[java]  view plain  copy
  1. package cn.hncu.search.oil.common;  
  2.   
  3. public class Myset {  
  4.     private Object[] objs= new Object[0];  
  5.     public boolean contains(Object obj){  
  6.         for(Object tmp: objs){  
  7.             if(tmp.equals(obj)){  
  8.                 return true;  
  9.             }  
  10.         }  
  11.         return false;  
  12.     }  
  13.     public boolean add(Object obj){  
  14.         if(contains(obj)){  
  15.             return false;  
  16.         }  
  17.         Object[] tempObjs = new Object[objs.length+1];  
  18.         System.arraycopy(objs, 0, tempObjs, 0, objs.length);  
  19.         tempObjs[objs.length] = obj;  
  20.         objs = tempObjs;  
  21.         return true;  
  22.     }  
  23.     public Object[] getAll(){  
  24.         return objs;  
  25.     }  
  26.     public int size(){  
  27.         return objs.length;  
  28.     }  
  29. }  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值