2015-04-16 58 views
2

假設有9個不同的卡和2個不同的玩家。當9張牌中每個玩家獲得3張牌時(總共6張牌)。在python中生成兩組組合與一個列表

如何生成將6張卡片分發給2個玩家的所有組合?

組合的數量很容易計算:

number_of_combinations = (9!/(6!*3!)) * (6!/(3!*3!)) = 1680 
  • PLAYER1得到內9卡3卡。可能的組合數是9!/(6!*3!)
  • Player2在剩下的6張牌中獲得3張牌。可能的組合數是6!/(3!*3!)

因此,將6張卡分發給2個玩家的所有組合是(9!/(6!*3!)) * (6!/(3!*3!)

但是生成組合看起來非常困難;這是我曾嘗試:

comb = itertools.combination([1,2,3,4,5,6,7,8,9], 6) 

但有一個問題:

比方說,有兩個列表,案例1和案例2。

case1 = [1,2,3 ,4,5,6] 
case2 = [1,2,4 ,3,5,6] 

對我而言,我必須以不同的方式處理case1和case2。

但是,如果我只是生成6個大小的組合,我不能這樣做。

+0

您的n_o_c公式缺少'/(N-K)'因素! – DSM

+0

@DSM和結果巧合正確:) – bereal

+0

@DSM OMG。謝謝 –

回答

4

要生產一個交易,你會使用random.sample() function隨機挑選6張牌;給第3〜播放器1,其餘部分與玩家2:

dealt_cards = random.sample(deck_of_cards, 6) 
player1_hand, player2_hand = dealt_cards[:3], dealt_cards[3:] 

爲了產生所有可能的組合然後,你會使用itertools.combinations()與大小6;但你仍然需要找到將這些6張卡片2手特有的所有可能的排列:

for dealt_cards in itertools.combinations(deck_of_cards, 6): 
    for hand1 in itertools.combinations(dealt_cards, 3): 
     hand2 = tuple(card for card in dealt_cards if card not in hand1) 
從6張牌每個處理組合

左右,3張牌所有組合被賦予一個球員,離開其他玩家剩下3張牌。

由此產生的解決方案的預期數量:

>>> from itertools import combinations 
>>> deck = range(9) 
>>> sum(1 for dealt in combinations(deck, 6) for _ in combinations(dealt, 3)) 
1680 

和演示:

>>> for dealt_cards in combinations(deck, 6): 
...  for hand1 in combinations(dealt_cards, 3): 
...   hand2 = tuple(card for card in dealt_cards if card not in hand1) 
...   print hand1, hand2 
... 
(0, 1, 2) (3, 4, 5) 
(0, 1, 3) (2, 4, 5) 
(0, 1, 4) (2, 3, 5) 
(0, 1, 5) (2, 3, 4) 
(0, 2, 3) (1, 4, 5) 
# ... 
(4, 6, 7) (3, 5, 8) 
(4, 6, 8) (3, 5, 7) 
(4, 7, 8) (3, 5, 6) 
(5, 6, 7) (3, 4, 8) 
(5, 6, 8) (3, 4, 7) 
(5, 7, 8) (3, 4, 6) 
(6, 7, 8) (3, 4, 5) 

你也可以製作只播放1手,然後與甲板的剩餘生產繼續玩家2手:

for hand1 in itertools.combinations(deck_of_cards, 3): 
    for hand2 in itertools.combinations([c for c in deck_of_cards if c not in hand1], 3): 
     # ... 

具有相同的預期計數輸出和結果:

>>> sum(1 for dealt in combinations(deck, 3) for _ in combinations([c for c in deck if c not in dealt], 3)) 
1680 
>>> for hand1 in combinations(deck, 3): 
...  for hand2 in combinations([c for c in deck if c not in hand1], 3): 
...   print hand1, hand2 
... 
(0, 1, 2) (3, 4, 5) 
(0, 1, 2) (3, 4, 6) 
(0, 1, 2) (3, 4, 7) 
(0, 1, 2) (3, 4, 8) 
(0, 1, 2) (3, 5, 6) 
# ... 
(6, 7, 8) (1, 3, 4) 
(6, 7, 8) (1, 3, 5) 
(6, 7, 8) (1, 4, 5) 
(6, 7, 8) (2, 3, 4) 
(6, 7, 8) (2, 3, 5) 
(6, 7, 8) (2, 4, 5) 
(6, 7, 8) (3, 4, 5) 

儘管現在順序不同。

+0

如果我理解正確,OP需要列舉兩名球員所有可能的牌。 – bereal

+0

是的。我需要所有可能的卡組合。 –

+0

@Martijn,我也試過itertools.combinations。我認爲只是生成大小爲6的組合並不是解決方案。 –

1
combinations = itertools.combinations(cards, 6) 

這將使你6張選擇卡,則需要分發的6卡之間的2名球員,所以:

possibilities = [] 
for combination in combinations: 
    hands = [] 
    hand1 = itertools.combinations(combination, 3) 
    hands.append(hand1)#Hand1 
    hands.append([x for x in combination if x not in hand1])#Hand2 
    possibilities.append(hands) 

,這將產生對每個項目是一個列表的列表possibilities兩個不同的手中。

+0

雖然我認爲這是正確的想法,但這不會像書面形式那樣工作。 – DSM

+0

是的,我有一個更簡單的版本,並編輯它,但搞砸了一些。我更新了它,它現在應該可以工作。 –

+0

現在你正在混合組合對象和手。例如,print(possible [0])。 – DSM

-1

只要獲得所有可能的6張卡片組合就不會削減它,因爲單個玩家手中的訂單無關緊要,但重要的是誰擁有哪張卡片。

所以對於出9的3卡的所有組合中,選擇3張其他卡出來的,其餘6:

from itertools import combinations 

def getCardCombinations(cards): 
    cards = set(cards) 
    for first in combinations(cards, 3): 
     for second in combinations(cards - set(first), 3): 
      yield first, second 

cards = [1,2,3,4,5,6,7,8,9] 

all_combinations = getCardCombinations(cards) 
-2

如果我理解你的權利,你想選擇6的每一個可能的組合出9.由於訂單並沒有真正的問題(我們可以把第3的選手1和第二批的3作爲球員2的手),我們可以只使用itertools.combinations

from itertools import combinations, izip 
hands = combinations(cards, 6) 

上午我理解你的問題T'

編輯:劃分這些成每3兩隻手,你會使用:

player1, player2 = izip(*map(lambda x: (x[:3], x[3:]), combinations(cards, 6))) 
+0

你不能只選擇9箇中的6個,也就是隻有84個組合,而不是預期的1680個。 –

+0

好點,我錯過了。我會編輯修復,但它看起來已經有一個正確的答案了,所以我只會贊成並繼續前進。 –

相關問題