分油的算法

来源:互联网 发布:oracle 示例数据库 hr 编辑:程序博客网 时间:2024/06/10 07:40

今天看一个分油的题目,来了兴趣,所以忍不住解一下.

 

原题

分油算法:一个桶中有12斤油,要求倒出6斤,可现在另外只有两个桶,分别可装8斤与5斤,请问应如何来倒?
补充:这里的12,6,8,5都是变量,应该可以自己设置,输出是每一次分油的步骤。

 

 

 

 

这里是用java,用过程语言也行,把实例变量用全局变量替换就好了.

这个问题有时候是无解的, 比如 25, 9 (要倒出来的油) ,8,5

无解的情况,稍微分析了一下,没有发现规律.

 

其实挺简单的,穷举递归.

MAXDEEP  超过21 之后 算法的时间就是分钟级的了,但是真有解的话,最优步长一般不超过15,一般是4 ~ 8.

 

有解需满足以下两个条件之一,没有经过验证,这可能会是一道有趣的数学题目.

如果要倒出的油在两个空桶的容量之间,或者小于总油量减去空桶的容量就会解

 

希望有兴趣的的朋友也尝试一下,看有没有更好和更确定的算法.


public class AllocateOil {
 
 private int capicity_x;
 private int capicity_y;
 private int capicity_z;
 
 private int goal;
 private int minDeep;
 
 public static int MAXDEEP = 20;
 
 private String stepExplain="Not Feasible";
 
 public AllocateOil(int x,int y,int z, int goal){
  capicity_x = x;
  capicity_y = y;
  capicity_z = z;
  this.goal = goal; 
  minDeep = MAXDEEP + 1;
 }
 
 public void allocate(int volumn_x,int volumn_y,int volumn_z,int deep,String stepExplain,int flag){
  if (deep >= Math.min(minDeep, MAXDEEP)  ) return;// only procee limited deep and got optimization method;
  
  int space_x = capicity_x - volumn_x;
  int space_y = capicity_y - volumn_y;
  int space_z = capicity_z - volumn_z;  
  stepExplain = stepExplain +  "/n" + "x:" + volumn_x + ",  y:" +volumn_y + ",  z:" +volumn_z;
  
  if(volumn_x == goal ||volumn_y == goal ||volumn_z == goal  ){
   if(deep < minDeep){
    this.stepExplain = stepExplain;
    minDeep = deep;
   }
   return;
  }
  
  // exchage X and Y
  if (volumn_x > 0  && space_y >0 && flag != -1  )
   allocate(volumn_x>space_y?volumn_x - space_y:0,volumn_x>space_y?capicity_y:volumn_x + volumn_y,volumn_z,deep + 1,stepExplain + "; x -> y ; step " + deep  , 1);
 
  if (volumn_y > 0  && space_x >0 && flag != 1  )
   allocate(volumn_y>space_x?capicity_x:volumn_x + volumn_y,volumn_y>space_x?volumn_y - space_x:0,volumn_z,deep + 1,stepExplain + "; y -> x ; step " + deep , -1);

  
  // exchage X and Z
  if (volumn_x > 0  && space_z >0 && flag != -2  )
   allocate(volumn_x>space_z?volumn_x - space_z:0,volumn_y,volumn_x>space_z?capicity_z:volumn_x + volumn_z,deep + 1,stepExplain + "; x -> z ; step " + deep , 2);
 
  if (volumn_z > 0  && space_x >0 && flag != 2  )
   allocate(volumn_z>space_x?capicity_x:volumn_x + volumn_z ,volumn_y,volumn_z>space_x?volumn_z - space_x:0,deep + 1,stepExplain + "; z -> x ; step " + deep , -2);

  
  // exchage Y and Z
  if (volumn_y > 0  && space_z >0 && flag != -3  )
   allocate(volumn_x,volumn_y>space_z?volumn_y - space_z:0,volumn_y>space_z?capicity_z:volumn_y + volumn_z,deep + 1,stepExplain + "; y -> z ; step " + deep , 3);
 
  if (volumn_z > 0  && space_y >0 && flag != 3  )
   allocate(volumn_x,volumn_z>space_y?capicity_y:volumn_y + volumn_z,volumn_z>space_y?volumn_y - space_z:0,deep + 1,stepExplain + "; z -> y ; step " + deep , -3);
  
 }
 
 public void allocate(){ 
  this.allocate(this.capicity_x,0,0,0,"",9);
  System.out.println(stepExplain);
 }
 
 public static void main(String[] args){ 
  AllocateOil alocOil = new AllocateOil(55,11,5,40);
  alocOil.allocate();  
 }

}

 

-----------------------------------------------------------

 

 

x:55,  y:0,  z:0; x -> z ; step 0
x:50,  y:0,  z:5; z -> y ; step 1
x:50,  y:5,  z:0; x -> z ; step 2
x:45,  y:5,  z:5; z -> y ; step 3
x:45,  y:10,  z:0; x -> z ; step 4
x:40,  y:10,  z:5