2010-11-19 57 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]}]