2010-11-19 69 views
3

AB成为列表。我要找到所有对{x,y},其中xA,y是在B和一些条件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___]并输出所有n个元组{x1,x2,...,xn},其中x1A1 ... xnAnCond[x1,x2,...,xn]是正确的。

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

谢谢!

回答

6

如果您需要检查所有对(即不存在对称使用减少的问题),那么最简单的可能是SelectTuples

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

哪做什么,我想你想:

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 *) 

希望这会有所帮助。

+0

啊! “元组”正是我所需要的(没有仔细阅读帮助文件)。谢谢! – MarkV 2010-11-19 01:44:56

1

另一种解决方案使用ReplaceList - 它比Janus的答案慢了约4倍(并且比原始方法慢了3倍),但是可能更高的内存效率。

In[1]:= allPairs1[a_,b_,cond_]:=Select[[email protected]{a,b},[email protected]@#&]; 
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 
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]}]