在阵列之间找到双射的算法

时间:2011-06-06 13:47:04

标签: algorithm wolfram-mathematica bijection

我有两个数组,比如A={1, 2, 3}B={2, 4, 8}(数组项数和数字可能会有所不同)。如何在阵列之间找到双射。

在这种情况下,它将是f:A->B; f(x)=2^(x)

3 个答案:

答案 0 :(得分:6)

我不认为这个问题有一个普遍的解决方案。您可以尝试FindSequenceFunction,但不会总是找到解决方案。对于手头的情况,您需要更长的列表:

In[250]:= FindSequenceFunction[Transpose[{{1, 2, 3}, {2, 4, 8}}], n]

Out[250]= FindSequenceFunction[{{1, 2}, {2, 4}, {3, 8}}, n]

但是

In[251]:= FindSequenceFunction[Transpose[{{1, 2, 3, 4}, {2, 4, 8, 16}}], n]

Out[251]= 2^n

如果您对双射有所猜测,也可以使用FindFit进行游戏:

In[252]:= FindFit[Transpose[{{1, 2, 3}, {2, 4, 8}}], p*q^x, {p, q}, x]

Out[252]= {p -> 1., q -> 2.}

答案 1 :(得分:4)

由于您标记了Mathematica,我将使用Mathematica函数作为参考。

如果您对使用平滑函数的数据的任意拟合感兴趣,可以使用插值。 E.g。

a = {1, 2, 3}; b = {2, 4, 8};
f = Interpolation[Transpose[{a, b}]];

(* Graph the interpolation function *)
Show[Plot[f[x], {x, 1, 3}], Graphics[Point /@ Transpose[{a, b}]], 
   PlotRange -> {{0, 4}, {0, 9}}, Frame -> Automatic, Axes -> None]

Plot of f

插值使用分段多项式。如果你知道或者愿意学习一些数值方法,特别是B-Splines,你可以用自己喜欢的编程语言做同样的事情。

相反,如果您对数据有所了解,例如:它的形式为c d ^ x,那么你可以做一个最小化来找到未知数(在这种情况下为c和d)。如果您的数据实际上是从c d ^ x形式生成的,那么拟合将是公平的,否则误差在最小二乘意义上被最小化。所以对于你的数据:

FindFit[Transpose[{a, b}], c d^x, {c, d}, {x}]

报告:

{c -> 1., d -> 2.}

表明你的功能是2 ^ x,就像你一直都知道的那样。

答案 2 :(得分:4)

正如其他人所说,这个问题是不明确的。

给出相同结果的其他可能函数(可能是无限其他函数):( 8 x)/ 3 - x ^ 2 + x ^ 3/3,x +(37 x ^ 2)/ 18 - (4 x ^ 3)/ 3 +(5×4)/ 18,和(259×3)/ 54 - (31×4)/ 9 +(35×5)/ 54。

我发现这些解决方案使用:

n = 5; (* try various other values *)
A = {1, 2, 3} ; B = {2, 4, 8}
eqs = Table[
  Sum[a[i] x[[1]]^i, {i, n}] == x[[2]], {x, {A, B}\[Transpose]}]
sol = Solve[eqs, Table[a[i], {i, n}], Reals]
Sum[a[i] x^i, {i, n}] /. sol

有时并非所有的[i]都完全确定,你可能会想出自己的价值观。

[提示:最好不要在Mathematica中使用以大写字母开头的变量,以免与保留字冲突]