很久没更新东西,这个学期比较忙~~~基于最近对大作业的探讨,写了一些比较有用的代码,拿出来分享一下。直接进主题:
SolveDiotN[A_List, M_] :=
Module[{T = {}, Y = {}, X, x, y, i, d, n, u},
n = Length[A];
Array[d, n];
X = Array[x, n];
For[i = 1, i <= n, i++, AppendTo[Y, x[i] >= 0]];
For[i = 1, i <= n, i++, AppendTo[T, x[i]]];
d[2] = GCD[A[[1]], A[[2]]];
For[i = 2, i <= n - 1, i++,
d[i + 1] = GCD[d[i], A[[i + 1]]]
];
If[Mod[M, d[n]] != 0, Return[-1],
u = T /. FindInstance[{\!\(
\*UnderoverscriptBox[\(\[Sum]\), \(i =
1\), \(n\)]\((A[\([\)\(i\)\(]\)]*x[i])\)\) == M &&
Apply[And, Y]}, X, Integers, M]
];
Return[u]
]
注意以上不是M文件,只是个Module结构,通俗点就是个自定义函数,M文件的制作方法已经讲过,大家可以自行制作。
注释的话也没有什么好说的,关键是调用了 FindInstance[]这个函数~~~~
求解n元一次不定方程本质就是穷举(对于计算机来说)。当然我这里求出的不是通解的表达式,而是针对实际的应用。举个调用的例子:
A={1,2,3};l=6;
SolveDiotN[A,l]; //相当于求x+2y+3z=6的所有非负整数的解
另外,注意Mathematica的版本是7.0~~~~
关于
u = T /. FindInstance[{\!\(
\*UnderoverscriptBox[\(\[Sum]\), \(i =
1\), \(n\)]\((A[\([\)\(i\)\(]\)]*x[i])\)\) == M &&
Apply[And, Y]}, X, Integers, M]
];
这段看起来貌似乱码的东西。是因为我在Mathematica中用二维的输入格式造成的,不用担心,直接复制到Mathematica中就OK的了。
最后说说比较有用的东西,就是Apply[]这个函数
(具体应用还是自己去执行 ?Apply 命令来查看细节),因为要满足对给定的n元都能产生出一系列x[1]>=0,x[2]>=0,..,x[n]>=0,的正整数条件,而对于Mathematica来说你只能写静态的条件即:
x[1] >= 0 && x[2] >= 0 && x[3] >= 0
很明显这样,并不能达到求n元的一般性。
而Apply[]就可以实现这样的目标。具体思路如下:
1)先构造集合Y={x[1]>=0,...,x[n]>=0}:
For[i=1,i<=n,i++,AppendTo[Y,x[i]>=0]]
这里不能不说Mathematica集合的一般性,就是允许集合的元素是表达式,当你使用这个集合的元素时,是对应的表达式是有意义的,而不仅是当成字符串。这点是很强大的!!
2)而现在的目标是构造出n个“且”的条件:
x[1] >= 0 && x[2] >= 0.... && x[n] >= 0
而&&的本质就是调用And[]函数,故所以只要用:
Apply[And,Y];
就能实现以上的动态条件
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL待 续LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL