[转载]用Mathematica写动态…

Mathematica动态规划算法,虽然不是我想要的路径算法T.T...但确实是好东西
原文地址:[转载]用Mathematica写动态规划程序 作者:Elisa
http://blog.dccmx.com/2011/09/dynamic-programming-in-mathematica/

最近系统莫名挂了,重装的时候整理了一下那些几百年没碰的文件。发现了一堆几年前写的Mathematica程序。悲剧的是:很多都看不懂了,当时是用这玩意来学习数学和函数式编程的。

挑了个有点意思的程序来复习一下。

问题是这样的:

有1, 2, 5, 10, 20, 50, 100, 200面值的钞票。用这些钞票(不限量),有多少种方法凑出200来(比如:1张200、2张100等)。

这种问题最优雅的解法就是动态规划。

Mathematica中提供了一些语法来方便我们写动态规划程序。

1.“/;”:用来表示规则成立的条件。例如可以这样定义绝对值函数:

1
2
3
4
5
6
In [13]:= abs[x_] /; x < 0 := -x;
abs[x_] /; x >= 0 := x;
 
In [15]:= {abs[1], abs[0], abs[-1]}
 
Out [15]= {1, 0, 1}

2.记住函数结果(动态规划精髓),即当可以将函数运算的结果存起了,下次用相同参数调用统一函数的时候,不需要重复计算,直接返回结果。语法是这样的:

1
f[x_, y_] := f[x, y] = x + y;

当第一次调用f[1,2]时,Mathematica将计算一次加法。第二次再调用f[1,2]时,直接返回3.

于是,上面的问题可以这样解决:

1
2
3
4
5
6
7
8
9
10
value = {1, 2, 5, 10, 20, 50, 100, 200};
Clear [NumberOfWay]; (*此处用于清除已保存的NumberOfWay[v_,n_],因为对于不同的value,这个值是不一样的*)
NumberOfWay[v_, n_] /; v > 0 && n > 0 :=
   NumberOfWay[v, n] =
    Sum [
     NumberOfWay[v - i value[[n]], n - 1],
     {i, 0, v/value[[n]]}
     ];
NumberOfWay[v_, 0] /; v > 0 := 0;
NumberOfWay[0, n_] /; n >= 0 = 1;
1
2
$RecursionLimit = Infinity ;
NumberOfWay[200, 8]

Mathematica真乃神器也!

你可能感兴趣的:(MCM)