【问题标题】:How to randomly match players into groups如何将玩家随机分组
【发布时间】:2019-12-04 20:39:06
【问题描述】:

我有一个像这样的 4 人(p1、p2、p3、p4)游戏:CSS Highlighting table row and column is not effective

我有两个这样的游戏 g1 和 g2,以及一些受试者 N,他们将作为每个 Player 玩这两个游戏,总共 8 轮。他们将面临固定的比赛顺序(例如,g1p3、g2p2、g1p2、g2p1、g2p3、g1p1、g2p4、g1p4)。他们的回报取决于他们选择的行动。

理想情况下,在每一轮中,受试者将被随机匹配成 4 人一组进行游戏,并且这 4 位受试者被随机分配一个角色。假设我有 8 个科目,他们在第一轮随机分为 2 组。在每个组中,假设 subject1 被随机分配为 Player1,subject2 被随机分配为 player2,依此类推。然后在他们完成这一轮之后,我可以根据他们选择的动作知道他们的收益。然后下一轮的类似程序,但我只是重新匹配组。但是,在我的设计中,每一轮中,每个科目都被分配到同一个角色,因为每个科目面对的游戏顺序是固定的,我无法进行上述匹配,所以我必须在科目都完成 8 后进行匹配回合。

我有一个想法:

  1. 我得到所有科目

  2. random.shuffle subject并得到前4个subjectswap = [a, b, c, d]

  3. 将它们分组:

        i = 0
        while i <= 3:
            groups = [players[x:x+4] for x in range(0, num_players, 4)]
            players.remove(swap[i])
            players.append(swap[i])
            i += 1
            for x in groups:
                group = x
                print('group', group)
                player_1 = group[0]
                player_2 = group[1]
                player_3 = group[2]
                player_4 = group[3]
                action1 = player_1.in_round(6).submitted_answer #get player's action when he is player 1 which is in round 6
                action2 = player_2.in_round(3).submitted_answer #get player's action when he is player 2 which is in round 3
                action3 = player_3.in_round(1).submitted_answer #get player's action when he is player 3 which is in round 1
                action4 = player_4.in_round(8).submitted_answer #get player's action when he is player 4 which is in round 8
                #code to determin the payoff based on the actions...

这是上述代码在 8 个主题的示例中的输出。例如,第一排玩家 3 扮演玩家 1 的角色,玩家 8 扮演玩家 2 的角色,玩家 5 扮演玩家 3 的角色,玩家 6 扮演玩家 4 的角色。例如,玩家 3 出现了 4 次,每次他扮演不同的角色。其他玩家也一样。这个功能是我需要的。

group [<Player  3>, <Player  8>, <Player  5>, <Player  6>]
group [<Player  4>, <Player  2>, <Player  7>, <Player  1>]
group [<Player  8>, <Player  5>, <Player  6>, <Player  4>]
group [<Player  2>, <Player  7>, <Player  1>, <Player  3>]
group [<Player  5>, <Player  6>, <Player  4>, <Player  2>]
group [<Player  7>, <Player  1>, <Player  3>, <Player  8>]
group [<Player  6>, <Player  4>, <Player  2>, <Player  7>]
group [<Player  1>, <Player  3>, <Player  8>, <Player  5>]

问题在于,除了第一场比赛之外,这并不是真正的随机比赛,因为在第一场比赛之后,玩家的顺序只是稍微改变了一点。我想要的是每场比赛都尽可能随机,并且他们的匹配方式可以确定他们在每一轮中的收益。

使用解决方案编辑虽然效率不高

import random
import itertools
import pprint

players = list(range(1,9))
num_groups = int(len(players)/4)


random.shuffle(players)
groups_round1 = [players[x:x+4] for x in range(0, len(players), 4)]
print('round1', groups_round1)
position_round1 = []
positions_round1 = {}
for k in players:
  position_round1 = [ x.index(k) for x in groups_round1 if k in x]
  positions_round1[k] = position_round1
all_groups={'round1': groups_round1}

i=2
while i <= 4:
  finish1 = False
  round_num = 'round' + str(i)
  all_groups[round_num]=[]
  while finish1 == False:
    random.shuffle(players)
    groups_base = [players[x:x+4] for x in range(0, len(players), 4)]
    possible_groups = [list(itertools.permutations(g)) for g in groups_base] 
    groups = []
    positions = {}
    positions[round_num] = {}
    a = 1
    for x in possible_groups:
      group = 'group' + str(a)
      positions[round_num][group]={}
      for y in x:
        for k in players:
          if k in y:
            position = [y.index(k)]
            positions[round_num][group][k] = position
        check = []
        for key in positions[round_num][group].keys():
          if i == 2:
            if positions[round_num][group].get(key, None) == positions_round1.get(key, None):
              break
            else:
              check.append('pass')
          elif i == 3:
            if positions[round_num][group].get(key, None) == positions_round1.get(key, None) \
            or positions[round_num][group].get(key, None) == positions_round2.get(key, None):
              break
            else:
              check.append('pass')
          elif i == 4:
              if positions[round_num][group].get(key, None) == positions_round1.get(key, None) \
              or positions[round_num][group].get(key, None) == positions_round2.get(key, None)\
              or positions[round_num][group].get(key, None) == positions_round3.get(key, None):
                  break
              else:
                  check.append('pass')
        condition = ['pass']*4
        if check == condition:
            groups.append(list(y))
            if i == 2:
                positions_round2={}
                for k in players:
                    position_round2 = [ x.index(k) for x in groups if k in x]
                    positions_round2[k] = position_round2
            elif i == 3:
                positions_round3={}
                for k in players:
                    position_round3 = [x.index(k) for x in groups if k in x]
                    positions_round3[k] = position_round3
            elif i == 4:
                positions_round4={}
                for k in players:
                    position_round4 = [x.index(k) for x in groups if k in x]
                    positions_round4[k] = position_round4
            all_groups[round_num]=groups
            break
      a += 1
    if int(len(groups)) == num_groups:
      finish1 = True
  print(round_num,groups)
  i += 1

带有样本输出:

round1 [[7, 8, 4, 2], [1, 3, 6, 5]]
round2 [[2, 5, 3, 1], [8, 6, 7, 4]]
round3 [[4, 1, 5, 7], [6, 2, 8, 3]]
round4 [[5, 7, 2, 6], [3, 4, 1, 8]]

【问题讨论】:

  • 能否添加一个有效的 Python 输入和相应的输出(例如)?至少对我来说,从问题的描述中不清楚你的意思是什么。

标签: python python-3.x


【解决方案1】:

您可以使用random.shuffle 来随机化玩家的整体顺序,然后按顺序分配组(即位置 1 到 4 的玩家进入第 1 组,位置 5 到 8 的玩家进入第 2 组,等等) .然后在每个组中,您可以使用itertools.permutations 生成角色分配。为了使这些随机化,您可以再次使用random.shuffle。下面是一些示例代码:

import itertools as it
import pprint
import random

N = 8
players = list(range(N))  # Players are identified by their integer id.

random.shuffle(players)  # Groups will be assigned in order, so shuffle beforehand.
groups = zip(*[iter(players)]*4)  # Group into 4-tuples.
groups = [list(it.permutations(g)) for g in groups]  # Assign roles within group.
for g in groups:
    random.shuffle(g)  # Shuffle the order of role assignment.

pprint.pprint(groups[0])  # For example group 1.

如果每轮都重新分配组

这里我们只能使用random.shuffle,因为分组和位置是按顺序分配的,所以如果玩家的顺序被打乱,分组和位置都是随机的:

import itertools as it
import pprint
import random

N = 8
players = list(range(N))  # Players are identified by their integer id.

groupings = []
for __ in range(5):  # Playing 5 rounds.
    random.shuffle(players)  # Groups and positions will be assigned in order, so shuffle beforehand.
    groupings.append(tuple(zip(*[iter(players)]*4)))  # Group into 4-tuples.

pprint.pprint(groupings)

带有示例输出:

[((5, 6, 7, 2), (4, 0, 3, 1)),
 ((7, 4, 2, 6), (0, 3, 5, 1)),
 ((2, 6, 1, 7), (4, 3, 0, 5)),
 ((5, 6, 1, 4), (2, 7, 0, 3)),
 ((4, 5, 2, 3), (6, 7, 0, 1))]

【讨论】:

  • 但组中的成员是固定的。我也想更改组中的成员。
  • @Jasmin 当然,每次您shuffle 并重新分配组时,这都会改变。所以你只需要把它放到另一个循环中。还是您只想使用一种配置运行,然后重新组合所有玩家?然后,您可以根据位置使用随机播放和组/角色分配。
  • 当然,但是如果将其放入另一个循环中,并不能确保每个玩家在新组中时都会处于不同的位置,是吗?
  • @Jasmin 它确实也确保了随机位置,因为两组 位置都是按顺序分配的,如果该顺序被打乱,那么两者都是随机的。请查看我的更新答案。
  • 知道了。例如,在您的示例输出中,1 位于 4 位置 3 次。如果我想在不重复的情况下每次在不同的位置进行 1 次表演,例如 4 轮,在位置 1、位置 3、位置 4 和位置 2 中每次将 1 分配到一组时,我想使用while 循环,直到满足上述条件,但它可能很耗时。
猜你喜欢
  • 2015-12-12
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
相关资源
最近更新 更多