Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一组玩家所有可能的牌/扑克组合_Python_Combinations_Permutation_Poker_Playing Cards - Fatal编程技术网

Python 一组玩家所有可能的牌/扑克组合

Python 一组玩家所有可能的牌/扑克组合,python,combinations,permutation,poker,playing-cards,Python,Combinations,Permutation,Poker,Playing Cards,我正在寻找一个优雅(快速)的python函数,它可以生成以下两个数组的所有组合 cards = ["8H", "8S", "8C", "8D", "9H", "9S", "9C", "9D", "10H", "10S", "10C", "10D", "AH", "AS", "AC", "AD"] players = ["_1", "_1", "_1", "_2", "_2", "_2", "_3", "_3", "_3", "_4", "_4", "_4", "_To", "_To", "_To

我正在寻找一个优雅(快速)的python函数,它可以生成以下两个数组的所有组合

cards = ["8H", "8S", "8C", "8D", "9H", "9S", "9C", "9D", "10H", "10S", "10C", "10D", "AH", "AS", "AC", "AD"]
players = ["_1", "_1", "_1", "_2", "_2", "_2", "_3", "_3", "_3", "_4", "_4", "_4", "_To", "_To", "_To", "_Tc"]
组合如下:

[('8H', '_1'), ('8S', '_1'), ('8C', '_1'), ('8D', '_2'), ('9H', '_2'), ('9S', '_2'), ('9C', '_3'), ('9D', '_3'), ('10H', '_3'), ('10S', '_4'), ('10C', '_4'), ('10D', '_4'), ('AH', '_To'), ('AS', '_To'), ('AC', '_To'), ('AD', '_Tc')]
但是!没有平等,这就是我的意思。 例如:

如果卡片是:

["a", "b", "c", "d"]
["1", "1", "2", "2"]
如果玩家愿意:

["a", "b", "c", "d"]
["1", "1", "2", "2"]
结果:

[1a, 1b, 2c, 2d]
[1a, 1c, 2b, 2d]
[1a, 1d, 2b, 2c]
[1b, 1c, 2a, 2d]
[1b, 1d, 2a, 2c]
[1c, 1d, 2a, 2b]
例如:

[1a, 1b, 2d, 2c]
玩家2的(c和d)等于(d和c)

我尝试了
itertools
的功能,比如
组合
排列
,但运气不佳。由于状态空间爆炸,在拥有所有组合后拒绝等于实际上不是一个选项


我希望有人能找到解决方案,因为谷歌搜索这个特定问题失败了。

好的,那么你真正想要的是:

set(tuple(zip(p, players)) for p in it.permutations(cards))
但这需要花费太多的时间。让我们试试看

cards = set(["8H", "8S", "8C", "8D", "9H", "9S", "9C", "9D", "10H", "10S", "10C", "10D", "AH", "AS", "AC", "AD"])

def deals(cards, players, cards_per_player):
    if not cards:
        yield []
        return
    for hand in it.combinations(cards, cards_per_player[0]):
        hand = set(hand)
        for deal in deals(cards - hand, players[1:], cards_per_player[1:]):
            yield zip([players[0]]*len(hand), hand) + deal

> for deal in deals(cards, ['_1', '_2', '_3', '_4', '_Tc', '_To'], [3,3,3,3,1,3]):
      print deal

这仍然需要很长的时间,但处理卡片的方法很多。

我建议使用递归算法

我使用生成器使代码在恒定的空间中运行,并尽快开始生成结果,而不是在最后生成巨大的结果;看看你以前是否听说过发电机

作为补充说明,我建议使用规范化的数据结构来保存玩家列表和手牌大小,这样就根本不需要使用
groupby
行了。。。在任何情况下,通常最好在默认情况下/大多数情况下保持数据的规范化,并且只使用非规范化/扁平化形式,例如,对于某些可能需要或使用扁平结构运行得更快的算法

这是代码;请随意提出清理/简化建议:

from itertools import combinations, groupby, islice

cards = ["a", "b", "c", "d"]
players = ["1", "1", "2", "2"]

def hand_combinations(players, cards):
    # convert ["1", "1", "2", "2"] into [("1", 2), ("2", 2)]
    players = list((x, len(list(y))) for x, y in groupby(players))

    # sets are faster to operate on in our case
    cards = set(cards)

    def generate(players, cards):
        if not players:
            yield []
        else:
            # pick the first player
            player_name, player_hand_size = players[0]
            # and then walk over all the possible hands for this player
            for player_hand in combinations(cards, player_hand_size):
                # for each hand, use the cards that are left to build all the
                # possible hands for the rest of the players in this iteration
                for tail in generate(players[1:], cards - set(player_hand)):
                    yield [(player_name, player_hand)] + tail

    return generate(players, cards)

# take only the 100 first combinations; otherwise it'll take
# forever with the larger example
combos = islice(hand_combinations(players, cards), 0, 100)

# convert back to the flat structure
flattened = [
    ' '.join(
        player_name + ':' + card
        for player_name, player_cards in combo
        for card in player_cards
    )
    for combo in combos
]

from pprint import pprint
pprint(flattened)
输出:

['1:a 1:c 2:b 2:d',
 '1:a 1:b 2:c 2:d',
 '1:a 1:d 2:c 2:b',
 '1:c 1:b 2:a 2:d',
 '1:c 1:d 2:a 2:b',
 '1:b 1:d 2:a 2:c']
或使用较大的可测试性:

['_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:8D _To:AH _To:9S _To:10D _Tc:8S',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:8D _To:AH _To:9S _To:8S _Tc:10D',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:8D _To:AH _To:10D _To:8S _Tc:9S',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:8D _To:9S _To:10D _To:8S _Tc:AH',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:10D _To:AH _To:9S _To:8D _Tc:8S',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:10D _To:AH _To:9S _To:8S _Tc:8D',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:10D _To:AH _To:8D _To:8S _Tc:9S',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:10D _To:9S _To:8D _To:8S _Tc:AH',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:AH _To:8S _To:9S _To:10D _Tc:8D',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:AH _To:8S _To:9S _To:8D _Tc:10D',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:AH _To:8S _To:10D _To:8D _Tc:9S',
 '_1:AS _1:9H _1:8H _2:AC _2:10H _2:AD _3:10S _3:10C _3:9C _4:8C _4:9D _4:AH _To:9S _To:10D _To:8D _Tc:8S',
...

你可以每人使用一组卡片,并将卡片按顺序排列,因此当你匹配这两组卡片时,它们将是相同的。 您可以为每张卡使用一个元组(大小为2),其中第一个元素可以表示范围(13)中的值,第二个元素是颜色(也可以用范围(4)中的数字表示)。你可以很容易地用双for循环生成牌组,可能是一个字典,在发牌后,你可以删除你已经使用过的牌,这样就不会有重复的牌,当你发完所有的牌时(如果你有代码,很容易修改它以拥有不同数量的玩家),你可以点牌,将其与您已有的数据库进行比较,如果存在匹配项,则不保存该数据库。如果您愿意,您还可以保存该组的其余部分,以便进行一些统计,这样您就可以对每种情况进行所有可能的处理,这将是一个巨大的数据库。这样,你将拥有所有的可能性,没有重复的手或手的球员。(一号玩家与二号玩家在不同的交易中进行交易,反之亦然) 我希望这对你或其他人有帮助。 我不会给出代码示例,因为这个问题更像是一个如何解决这个问题的问题,其他人给了你一些编码技巧。即使您刚刚开始使用python,并且到目前为止只做了一些教程,也可以使用这种方法。
祝你好运;)

这只会导致一个组合,我需要所有组合。就像abcd例子一样。现在查看产品功能。@user3411641好的,我明白你的意思了。更新。我已经使标题和标签对这个问题更加合适和相关;上一个标题不是人们将要搜索这个特定(与扑克相关)问题的东西。“space”和“state”标记是在没有注意它们的含义的情况下选择的。@user3411641:也许我遗漏了一些东西,但我真的看不出在哪里可以优化任何东西。。。如果您不急于求值,则代码应在常量空间中运行,并在启动后立即发出结果。好吧,更重要的是,如果您正确使用返回值(即惰性地使用),则上述代码不会溢出/填充内存。@user3411641:如果您正确使用返回值,则上述代码不会溢出/填充内存。有关如何充分利用生成器/惰性的更多信息,请参阅提供的有关生成器的链接。