穷举法求解泊松分酒问题

一. 泊松分酒的简单介绍

  泊松是法国数学家、物理学家和力学家。他的一生致力于科学事业,成果颇多。有许多著名的的公式定理都是以他的名字命名,比如大学中学习的概率论中的泊松分布,再有一次闲暇时,他提出过一个非常有趣的问题,后来被称为:"泊松分酒问题"。

  有三个容器,既就是三个酒杯 它们的的容量分别为 12升 , 7升 , 5升,三个酒杯中的初始酒量分别为 12升,0升,0升,要求你只用这三个酒杯进行操作,最后使得某一个酒杯中的酒正好是 6升酒?

二. 穷举算法

用穷举法解题时,就是按照某种方式列举问题答案的过程。针对问题的数据类型而言,常用的列举方法一有如下三种:
(1)顺序列举 是指答案范围内的各种情况很容易与自然数对应甚至就是自然数,可以按自然数的变化顺序去列举。
(2)排列列举 有时答案的数据形式是一组数的排列,列举出所有答案所在范围内的排列,为排列列举。
(3)组合列举 当答案的数据形式为一些元素的组合时,往往需要用组合列举。组合是无序的。

三. 穷举法求解泊松分酒问题

 1 /**
 2  * 1.穷举
 3  *  泊松分酒
 4  */
 5 public class Exhaustion {
 6      //三个酒杯 的容量分别为 12L , 7L , 5L
 7      //三个酒杯的初始酒量:12L ,  0L , 0L
 8      //在三个容器中互相到,直到到处  6L酒
 9      
10      //三个酒杯 的容量分别为 12L , 7L , 5L
11      private int wineGlass1=12;
12      private int wineGlass2=7;
13      private int wineGlass3=5;
14      private int target=6;   //目标酒量
15      
16      /**
17       * 倒酒方法
18       * @param b1   酒杯wineGlass1 的实际酒量
19       * @param b2   酒杯wineGlass2 的实际酒量
20       * @param b3   酒杯wineGlass3 的实际酒量
21       */
22      private  void pourWine(int b1,int b2,int b3) {
23           
24           System.out.println("酒杯wineGlass1 的实际酒量为:"+b1
          +" 酒杯wineGlass2 的实际酒量为: "+b2+
            " 酒杯wineGlass3 的实际酒量为: "+b3); 25 //假设一开始三个酒杯的初始酒量: b1=12,b2=0,b3=0 26 //指定一定的倒酒策略:防止重复倒酒,做无用功,甚至死循环 27 //酒杯wineGlass1——>酒杯wineGlass2——>酒杯wineGlass3——>酒杯wineGlass1 28 29 //任意一个酒杯的酒量为 目标酒量时,就可以不用再倒酒了 30 if(b1==target||b2==target||b3==target) { 31 System.out.println("此时刚好可以到处目标酒量6L"); 32 return; 33 } 34 35 //先从酒杯wineGlass2开始判断 36 //如果酒杯wineGlass2 中还有酒,并且酒杯wineGlass3 还未倒满 37 if(b2!=0&&b3!=wineGlass3) { 38 //将酒杯wineGlass2 中的酒 继续倒入酒杯wineGlass3 39
          //将酒杯wineGlass2 中的酒全部倒入酒杯wineGlass3,酒杯wineGlass3还未满 40 if(b2+b3<wineGlass3) {41 //下一轮倒酒 42 pourWine(b1, 0, b2+b3); 43 }else { //将酒杯wineGlass2 中的酒全部倒入酒杯wineGlass3,酒杯wineGlass3溢出,
               //所以最多只能将酒杯wineGlass3倒满
                
44 //倒入酒杯wineGlass3的酒量为:wineGlass3-b3 45 pourWine(b1, b2-(wineGlass3-b3), wineGlass3); 46 } 47 //判断酒杯wineGlass3 的情况: 48 }else if(b3==wineGlass3) {//如果 酒杯wineGlass3 已经满了 ,往酒杯wineGlass1 里倒 49 //全部倒完 酒杯wineGlass3中的酒倒入酒杯wineGlass1,酒杯wineGlass1中的酒还未满 50 if(b3+b1<wineGlass1) { 51 pourWine(b1+b3, b2, 0); 52 }else { //将酒杯wineGlass3中的酒 倒满 酒杯wineGlass1之后,
              //酒杯wineGlass3中的酒还有剩余
53 //酒杯wineGlass1 实际倒入的酒量 为:wineGlass1-b1 54 pourWine(wineGlass1, b2, b3-(wineGlass1-b1)); 55 } 56 //酒杯wineGlass2的实际酒量为 0 57 }else if(b2==0) { 58 //将酒杯wineGlass1中的酒 倒满 酒杯wineGlass2之后,酒杯wineGlass1中的酒还有剩余 59 //实际倒入wineGlass2中的酒为:wineGlass2-b2 60 if(b1>b2) { 61 //注意:wineGlass2 酒杯的实际酒量为 0 62 pourWine(b1-wineGlass2, wineGlass2, b3); 63 }else { //全部倒完 酒杯wineGlass1中的酒倒入酒杯wineGlass2,
               //酒杯wineGlass2中的酒还未满
64 //注意:wineGlass2 酒杯的实际酒量为 0 65 pourWine(0, b1, b3); 66 } 67 } 68 69 } 70 71 public static void main(String[] args) { 72 Exhaustion exhaustion=new Exhaustion(); 73 System.out.println("酒杯wineGlass1 的最大容量为:"+exhaustion.wineGlass1+
          " 酒杯wineGlass2 的最大容量为: "+exhaustion.wineGlass2+
            " 酒杯wineGlass3的最大容量为: "+exhaustion.wineGlass3); 74 75 System.out.println("--------------------------------------"); 76 exhaustion.pourWine(12, 4, 0); 77 } 78 79 }

四. 运行结果

酒杯wineGlass1 的最大容量为:12 酒杯wineGlass2 的最大容量为: 7 酒杯wineGlass3的最大容量为: 5
------------------------------------------------------------------------
酒杯wineGlass1 的实际酒量为:12    酒杯wineGlass2 的实际酒量为: 4    酒杯wineGlass3 的实际酒量为: 0
酒杯wineGlass1 的实际酒量为:12    酒杯wineGlass2 的实际酒量为: 0    酒杯wineGlass3 的实际酒量为: 4
酒杯wineGlass1 的实际酒量为:5    酒杯wineGlass2 的实际酒量为: 7    酒杯wineGlass3 的实际酒量为: 4
酒杯wineGlass1 的实际酒量为:5    酒杯wineGlass2 的实际酒量为: 6    酒杯wineGlass3 的实际酒量为: 5
此时刚好可以到处目标酒量6L

 

posted @ 2017-12-06 21:37  别人放弃,我依旧坚持  阅读(1282)  评论(0编辑  收藏  举报