找到满足一定条件的对的有效方法

时间:2010-11-19 01:05:36

标签: wolfram-mathematica

AB成为列表。我要找到所有{x,y} x A yB位于Cond[x,y]且某些条件AllPairs[A_, B_, Cond_] := Module[{i, k, C, Cp}, C = {}; For[i = 1, i <= Length[A], i++, Cp = Select[B, Cond[A[[i]], #] &]; C = C~Join~Table[{A[[i]], Cp[[k]]}, {k, 1, Length[Cp]}]; ]; Return[C]; ] 为真的对In[1]:= AllPairs[{1, 2, 3, 4}, {3, 4, 5}, EvenQ[#1 + #2] &] Out[1]:= {{1, 3}, {1, 5}, {2, 4}, {3, 3}, {3, 5}, {4, 4}} 。这就是我想出的,但它非常麻烦,我怀疑有更好的方法

A1, A2,...,An

例如

Cond[x___]

我对此代码的另一个问题是它不容易概括。我想有一个函数,它接收列表{x1,x2,...,xn}和一些条件x1,并输出A1所在的xn的所有n个元组An。 。Cond[x1,x2,...,xn]位于{{1}}且{{1}}为真。

最后,是否有内置函数来计算两个或更多列表的 cartesian product

谢谢!

3 个答案:

答案 0 :(得分:6)

如果你需要检查所有对(即没有用于减少问题的对称性),那么最简单的可能是SelectTuples

allPairs[a_,b_,cond_]:=Select[Tuples@{a,b},cond@@#&];

我认为你想要的是什么:

a=Range[4]; b=Range[3,5];
allPairs[a,b,EvenQ[#1+#2]&]
Out[37]= {{1,3},{1,5},{2,4},{3,3},{3,5},{4,4}}

至于生成对的更多工具,请查找TuplesOuter

Tuples[a,2] (* 2-tuples with entries from a *)
Tuples[{a,b}] (* 2-tuples with firt (2nd) entry from a (b) *)
Outer[List,a,b] (* cartesian product *)

希望这有帮助。

答案 1 :(得分:2)

对于这样的问题,我个人喜欢使用案例并附上条件。不过,我不确定效率。

lst1 = {1, 2, 3, 4};
lst2 = {3, 4, 5};
Cases[Tuples[{lst1, lst2}], {x_, y_} /; EvenQ[x + y]]

我发现这种方法简单而通用,至少对于小型列表(我使用的类型!)

Cases[Tuples[{lst1, lst2}], {x_ /; EvenQ[x], y_ /; OddQ[y]}]

答案 2 :(得分:1)

另一种解决方案使用ReplaceList - 它比Janus的答案慢约4倍(比原始方法慢3倍),但可能更有效。

In[1]:= allPairs1[a_,b_,cond_]:=Select[Tuples@{a,b},cond@@#&];
In[2]:= allPairs2[a_,b_,cond_]:=ReplaceList[{a,b},
                                  {{___,x_,___},{___,y_,___}}/;cond[x,y]:>{x,y}]

In[3]:= aa=RandomInteger[{0,10^5},{1000}];
In[4]:= bb=RandomInteger[{0,10^5},{1000}];

In[5]:= test1=allPairs1[aa,bb,EvenQ[#1+#2]&];//Timing
Out[5]= {4.99,Null}

In[6]:= test2=allPairs2[aa,bb,EvenQ[#1+#2]&];//Timing
Out[6]= {19.12,Null}

In[7]:= test1==test2
Out[7]= True