hujunhua 发表于 2017-4-12 10:48:08

第一个问题,三只杯子只要定好出入方向,B12总是以B8和B5整杯出入,总能达到结果。所谓定好方向,就是过程中A杯与B杯若有授受,只能是A杯倒向B杯,不能反之。
只有两个方向:顺向(B12→B8→B5→B12),逆向(B12→B5→B8→B12)
顺向M10程序及结果:
NestWhileList[
Which[
   First@# == 0, # + {8, -8, 0},(*若B8为空,则用它从B12中量出8升水*)
   Last@# == 5, # + {0, 5, -5},(*若B5装满,则将B5全部倒入B12*)
   True, # + {-1, 0, 1} Min] &,(*若B8不空,B5不满,则将B8中的水倒入B5,倒空B8或者装满B5*)
{0, 12, 0}, (*{B8, B12, B5}的初值*)
# != {6, 6, 0} & (*{B8, B12, B5}的终值*)
]
Out={{0, 12, 0}, {8, 4, 0}, {3, 4, 5}, {3, 9, 0}, {0, 9, 3}, {8, 1,   3}, {6, 1, 5}, {6, 6, 0}}

逆向M10程序及结果:
NestWhileList[ Which[ Last@# == 0, # + {0, -5, 5}, First@# ==8, # + {-8, 8, 0}, True, # + {1, 0, -1} Min] &, {0, 12, 0}, # != {6, 6, 0} &]
={{0, 12, 0}, {0, 7, 5}, {5, 7, 0}, {5, 2, 5}, {8, 2, 2}, {0, 10, 2}, {2, 10, 0}, {2, 5, 5}, {7, 5, 0}, {7, 0, 5}, {8, 0, 4}, {0, 8, 4}, {4, 8, 0}, {4, 3, 5}, {8, 3, 1}, {0, 11, 1}, {1, 11, 0}, {1, 6, 5}, {6, 6, 0}}

两个方向的输出结果正好包含了全部25个状态。

hujunhua 发表于 2017-4-12 11:12:05

顺向是最短路径,而逆向是最长路径吧。逆向结果中明显可以从{0,7,5}改变方程和定量直接到{7,0,5}.

保持方向和定量的好处就是在你事先不知道路线图时,总能找到终点,不用费神去想什么时候改变策略可有捷径。

如果你没有路线图,又没有规则(方向和定量),随意地变来变去想碰到捷径,就会在迷宫里转圈圈。

mathematica 发表于 2018-7-23 16:17:37

hujunhua 发表于 2017-4-12 10:48
第一个问题,三只杯子只要定好出入方向,B12总是以B8和B5整杯出入,总能达到结果。所谓定好方向,就是过程 ...

Clear["Global`*"];(*Clear all variables*)
(*水的方向只能是从A到B,从B到C,从C到A这样运行*)
a=32; b=23; c=9;(*三只水杯的容积*)
aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
Do[
    (*如果B杯空了,就把A杯的水倒满B杯*)
    If;Break[]];a2b=b;aa=aa-a2b;bb=bb+a2b;Print@{aa,bb,cc}];
    (*把B杯的水尽可能地倒向C杯*)
    If;bb=bb-b2c;cc=cc+b2c;Print@{aa,bb,cc}];
    (*如果C杯满了,就全部倒向A杯*)
    If;Break[]];c2a=c;aa=aa+c2a;cc=cc-c2a;Print@{aa,bb,cc}];
    If],
    {k,1,100}
]

如果水的总体积大于最大的水杯的容积,那么如何操作呢?上面的程序就bug了!

运行结果如下:
{32,0,4}
{9,23,4}
{9,18,9}
{18,18,0}
{18,9,9}
{27,9,0}
{27,0,9}

BUG!!

mathematica 发表于 2018-7-23 16:25:08

a=32; b=23; c=9;(*三只水杯的容积*)
aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
能够做到使得A杯里面水的体积是19吗?

Clear["Global`*"];(*Clear all variables*)
(*水的方向只能是从A到B,从B到C,从C到A这样运行*)
a=32; b=23; c=9;(*三只水杯的容积*)
aa=32;bb=4;cc=0;(*三只水杯里面的水的体积*)
Do[
    (*如果B杯空了,就把A杯的水倒满B杯*)
    If;
    (*把B杯的水尽可能地倒向C杯*)
    If;bb=bb-b2c;cc=cc+b2c;Print@{aa,bb,cc}];
    (*如果C杯满了,就全部倒向A杯*)
    If[(cc==c)&&(aa+cc<=a),c2a=c;aa=aa+c2a;cc=cc-c2a;Print@{aa,bb,cc}];
    If],
    {k,1,200}
]

{32,0,4}
{9,23,4}
{9,18,9}
{18,18,0}
{18,9,9}
{27,9,0}
{27,0,9}
{4,23,9}
{13,23,0}
{13,14,9}
{22,14,0}
{22,5,9}
{31,5,0}
{31,0,5}
{8,23,5}
{8,19,9}
{17,19,0}
{17,10,9}
{26,10,0}
{26,1,9}

看这代码的运行结果,似乎没解,但是问题是否有解呢?

lsr314 发表于 2018-7-25 11:09:17

解方程$32+23x+9y=19$,得$x=1,y=-4$,那么
{32,4,0}
{23,4,9}
{23,13,0}
{14,13,9}
{14,22,0}
{5,22,9}
{5,23,8}
{28,0,8}
{28,8,0}
{19,8,9}

kastin 发表于 2022-7-7 15:06:56

5+(-1)=4,-1=2-3,2=5-3
5L满杯倒入3L满杯,3L杯清空,5L杯子中剩余2L水倒入3L杯,5L杯再倒满,然后往装有2L水的3L杯倒满,剩余即为5L杯中装有4L水。
页: 1 2 3 [4]
查看完整版本: 求水杯问题的终极解答!