2013-11-20 64 views
2

我正在實施本文中的並行DC3,pDC3算法:http://algo2.iti.kit.edu/sanders/papers/KulSan06a.pdf實現特定的比較功能

見第12行:

""" 
Sort S0 U S1 U S2 using the comparison function: 
    (c, ...) in S1 U S2 <= (d, ...) in S1 U S2 <=> c <= d 
    (t, t', c', c'', i) in S0 <= (u, u', d', d'', j) in S0 <=> (t, c') <= (u, d') 
    (t, t', c', c'', i) in S0 <= (d, u,  d', j) in S1 <=> (t, c') <= (u, d') 
    (t, t', c', c'', i) in S0 <= (d, u, u', d'', j) in S2 <=> (t, t', c'') <= (u, u', d'') 
""" 

我將如何實現在Python這樣的比較?

對不起,我還沒有在這裏給出完整的圖片。但是,讓我回去了幾步,顯示什麼S0-S2的樣子在我的實現:

我的代碼的最後幾行,我計算S0-S2:

s0 = computeS0(indexSortedRankIndexPairs, text, paddedText) 
print 'Set0:       ' + str(s0) 

s1 = computeS1(indexSortedRankIndexPairs, text, paddedText) 
print 'Set1:       ' + str(s1) 

s2 = computeS2(indexSortedRankIndexPairs, text, paddedText) 
print 'Set2:       ' + str(s2) 

這是樣本輸出從我的程序:

Text       yabbadabbado 
Padded Text     yabbadabbado00 
Trituples:      set([('ada', 4), ('bba', 7), ('abb', 1), ('o00', 11), ('do0', 10), ('bad', 8), ('bba', 2), ('dab', 5)]) 
Sorted Trituples:    [('abb', 1), ('ada', 4), ('bad', 8), ('bba', 7), ('bba', 2), ('dab', 5), ('do0', 10), ('o00', 11)] 
Rank Index Pairs:    [(1, 1), (2, 4), (3, 8), (4, 7), (4, 2), (5, 5), (6, 10), (7, 11)] 
Sorted Rank Index Pairs:  [(1, 1), (2, 4), (4, 7), (6, 10), (4, 2), (5, 5), (3, 8), (7, 11)] 
Index Sorted Rank Index Pairs: [(1, 1), (4, 2), (2, 4), (5, 5), (4, 7), (3, 8), (6, 10), (7, 11)] 
Set0:       set([('a', 'd', 6, 7, 9), ('y', 'a', 1, 4, 0), ('a', 'b', 4, 3, 6), ('b', 'a', 2, 5, 3)]) 
Set1:       set([(2, 'a', 5, 4), (1, 'a', 4, 1), (4, 'b', 3, 7), (6, 'd', 7, 10)]) 
Set2:       set([(7, 'o', '0', 0, 11), (3, 'b', 'a', 6, 8), (5, 'd', 'a', 4, 5), (4, 'b', 'b', 2, 2)]) 

所以,S0,S1和S2基本上是本地Python集(至少現在)。

+1

首先你要告訴我們你是如何代表S0,S1,S2或者,或者我們必須拿出我們自己執行所有前面的代碼,這是(a)更多的工作任何人都想爲你做,並且(b)會迫使你從其他人的實施轉化爲你的人,而不是直接使用它。 – abarnert

+0

請您詳細說明什麼是什麼。 – tMJ

+0

另外,你有閱讀[排序如何](http://docs.python.org/3/howto/sorting.html)?你意識到Python排序函數需要一個'key'函數來轉換兩個值,而不是比較兩個值的比較函數?您可以編寫一個比較函數,然後將其包裝在'functools.cmp_to_key'中,但這通常不是最佳解決方案。 – abarnert

回答

1

我想我可以在這裏給你一些總體想法。

假設你正在使用Python 2.x的

這將是我的問題解決辦法:

Set0 = set([('a', 'd', 6, 7, 9), ('y', 'a', 1, 4, 0), ('a', 'b', 4, 3, 6), ('b', 'a', 2, 5, 3)]) 
    Set1 = set([(2, 'a', 5, 4), (1, 'a', 4, 1), (4, 'b', 3, 7), (6, 'd', 7, 10)]) 
    Set2 = set([(7, 'o', '0', 0, 11), (3, 'b', 'a', 6, 8), (5, 'd', 'a', 4, 5), (4, 'b', 'b', 2, 2)]) 


    def make_s0(s): 
     # add an element to the tuple to 'tag' the set 
     return [('s0', a, b, c, d, e) for (a, b, c, d, e) in s] 

    def make_s1(s): 
     return [('s1', a, b, None, d, e) for (a, b, d, e) in s] 

    def make_s2(s): 
     return [('s2', a, b, c, d, e) for (a, b, c, d, e) in s] 

    def cmp_elem(l, r): 
     # you need to complete the implementation here 
     # based on the first element of the tag to carry out comparsion 
     if l[0] == 's0' and r[0] == 's0': 
      (_, t, tdash, cdash, cdashdash, i) = l 
      (_, u, udash, ddash, ddash, j) = r 
      return cmp((t, cdash), (u, ddash)) 
     elif (l[0] == 's1' and r[0] == 's2') or (l[0] == 's2' and r[0] == 's1'): 
      (_, c, _, _, _, _) = l 
      (_, d, _, _, _, _) = r 
      return cmp(c, d) 
     return 0 

    if __name__ == "__main__": 
     l = make_s0(Set0) + make_s1(Set1) + make_s2(Set2) 
     print sorted(l, cmp=cmp_elem) 

閱讀本http://docs.python.org/3.3/howto/sorting.html轉換上面的代碼在Python運行3個

+0

感謝您的幫助。該算法的結果是:[('s0','b','a',2,5,3),('s0','y','a',1,4,0​​) ('s0','a','b',4,3,6),('s0','a','d',6,7,9),('s1',2,'a ('s1',1,'a',None,4,1),('s1',4,'b',None,3,7),('s1', ('s2',7,'o','0',0,11),('s2',3,'b','a',6,'d',None,7,10) ('s2',5,'d','a',4,5),('s2',4,'b','b',2,2')' ,其不幸地包括s0 ,s1,s2不應該在那裏。 – p0lAris

+0

當然,您需要自己完成實施。刪除元組中的第一個元素將非常容易。看看我如何在函數make_s0/1/2中使用列表理解 –

+0

第二種情況需要處理來自S1的來源和來自S2的來源。所以只需要'elif'l [0]!='s0'和r [0]!='s0':'在那裏。另外,我認爲按照指定的順序寫下它們會更清楚一些,而不是將前兩種情況寫成亂序。 – abarnert

0

規則像這樣看起來很容易容納在一個關鍵功能

(c, . . .) ∈ S1 ∪ S2 ≤ (d,. . .) ∈ S1 ∪ S2 ⇔ c ≤ d 
(t, t′ , c′ , c′′, i) ∈ S0 ≤ (u, u′ , d′, d′′, j) ∈ S0 ⇔ (t, c′) ≤ (u, d′) 

但我怎麼看不到這些的,可以這麼容易accomodated

(t, t′, c′, c′′, i) ∈ S0 ≤ (d, u,  d′, j) ∈ S1 ⇔ (t,c′) ≤ (u, d′) 
(t, t′, c′, c′′, i) ∈ S0 ≤ (d, u, u′, d′′, j) ∈ S2 ⇔ (t,t′, c′′) ≤ (u, u′, d′′) 

你可能不得不退回到使用比較函數用於排序

在Python2,你仍然可以使用棄用cmp=參數
在Python3,使用functools.cmp_to_key並傳遞到key=參數

+0

這並沒有真正給出如何編寫這樣一個'cmp'函數的指導,這是這個問題的實際困難部分。不知何故,你必須知道這些值是來自S1,S0還是S2。如果沒有辦法從帶內信息中得知這一點,那就意味着您必須標記它們,就像孔安東的答案一樣。一旦你解決了這個問題,其餘的(相對)簡單,但你必須解決這個問題,否則你沒有答案。 – abarnert

+0

@abarnert,我仍然試圖看看是否有一個關鍵功能的竅門。 –

+0

用關鍵函數做這件事的明顯「正確」方法是用適當的'__lt__'方法返回S0,S1和S2對象,這些方法知道如何與其他類型進行比較。在這種情況下,你真的不需要'鍵'功能;更好地裝飾物體並留下裝飾物。 (特別是如果這些類繼承自'namedtuple',那麼裝飾將不會破壞任何可能存在的代碼。) – abarnert