Python甚至组分配

时间:2018-08-30 02:21:43

标签: python random

我是python的初学者,正在研究随机团队生成器。我遇到的问题是我不确定如何使它产生甚至团队。下面是代码以及示例输出。

import random


def main():
    run = True
    while run:

        try:
            print("Welcome to this group picker, follow the instructions and your groups will be picked.")
            groupnum = int(input("How many groups do you want?"))
            peoplenum = int(input("How many people are there?"))
            print("Okay, assign everyone a number from 0 to", peoplenum - 1, ".")
            nums = []
            for i in range(0, peoplenum):
                nums.append(i)

            for i in nums:
                print("Number", i, "is in group", random.randint(1, groupnum))

            break

        except:
            print("Error, please follow instructions and enter only numbers.")
            break


main()

示例输出:

 Welcome to this group picker, follow the instructions and your groups
 will be picked.
 How many groups do you want?2 
 How many people are there?8
 Okay, assign everyone a number from 0 to 7 . 
 Number 0 is in group 1 
 Number 1 is in group 2 
 Number 2 is in group 1 
 Number 3 is in group 2 
 Number 4 is in group 1 
 Number 5 is in group 1 
 Number 6 is in group 2 
 Number 7 is in group 1

6 个答案:

答案 0 :(得分:1)

仅使用标准库,我将这样解决:

import random
from itertools import accumulate


def print_groups(n, g):
    # Prepare group separators
    size = n // g
    rem = n % g
    separators = list(accumulate([0] + [size+1] * rem + [size] * (g - rem)))

    # Make raw data
    items = list(range(n))
    random.shuffle(items)

    # Iterate and print
    for i, s in enumerate(zip(separators, separators[1:])):
        group = items[slice(*s)]
        print(f'Group {i+1}: {group} (size {len(group)})')

如果您的人数可被组的数量整除,则所有组的大小将相同,否则前n % g个组将获得一个额外的成员。

示例1:

print_groups(12, 4)

Group 1: [6, 11, 10] (size 3)
Group 2: [7, 2, 5] (size 3)
Group 3: [3, 1, 9] (size 3)
Group 4: [4, 8, 0] (size 3)

示例2:

print_groups(14, 4)

Group 1: [8, 3, 4, 6] (size 4)
Group 2: [1, 11, 0, 12] (size 4)
Group 3: [7, 5, 9] (size 3)
Group 4: [13, 10, 2] (size 3)

答案 1 :(得分:1)

问题是为每个球员随机挑选一支球队。由于random.randint产生均等的价值分配,因此每个球员都有被分配给任何给定团队的相同机会,因此您可以最终成为同一团队中的每个人。

相反,您应该考虑遍历各个团队并为其分配一个随机的玩家。

该想法的实施不佳会

>>> import random
>>> 
>>> groupnum = 2
>>> peoplenum = 8
>>> 
>>> people = [i for i in range(peoplenum)]
>>> 
>>> for i in range(peoplenum):
...     group = i % groupnum
...     person = random.choice(people)
...     people.remove(person)
...     print('Number {} assigned to {}'.format(person, group))
... 
Number 6 assigned to 0
Number 7 assigned to 1
Number 4 assigned to 0
Number 3 assigned to 1
Number 2 assigned to 0
Number 5 assigned to 1
Number 1 assigned to 0
Number 0 assigned to 1

这将解决问题,但它依靠致电remove来避免重复团队成员。为避免这种情况,您可以随机排列玩家列表(使其随机排列),并在团队列表中zip将结果{}。

>>> import random
>>>
>>> players = [i for i in range(peoplenum)]
>>> teams = [i for i in range(groupnum)]
>>> 
>>> random.shuffle(players)
>>> 
>>> [x for x in zip(players, teams)]
[(7, 0), (5, 1)]

这显然行不通。这是因为zip将在最短的迭代器停止时停止,在本例中为groups。我们想要的是在有玩家的情况下重复播放。我们可以使用itertools.cycle实现这种功能:

>>> import random
>>> import itertools
>>> 
>>> players = [i for i in range(peoplenum)]
>>> teams = itertools.cycle(range(groupnum))
>>> 
>>> random.shuffle(players)
>>> 
>>> [x for x in zip(players, teams)]
[(7, 0), (2, 1), (0, 0), (1, 1), (5, 0), (4, 1), (3, 0), (6, 1)]

答案 2 :(得分:0)

根据组数调整每个组的概率。使用while循环可连续分配组,并且仅在组的总和相等时才返回。

答案 3 :(得分:0)

我将使用numpy.random.choice进行此操作,并将replace设置为false。 See relevant numpy documentation here

尝试使用此代码:

import numpy as np

def assign_people_to_teams(people_count = 8, team_count = 2):
    """
        selects people_count random numbers in the range 0 to people_count-1 without replacement
        then make a team assignment decision based on desired number of teams.
    """
    return [
        element % team_count for element in list(
            np.random.choice(
                people_count,
                people_count,
                replace=False
            )
        )
    ]

team_assignment = assign_people_to_teams()

print(team_assignment)

结果:

[0, 0, 1, 0, 0, 1, 1, 1]

答案 4 :(得分:0)

您将必须为每个组使用一组,然后为该人选择随机组。一旦每个组都用尽,然后重复直到所有组都填满。

import random
import sys


def main():
    while True:

        try:
            print("Welcome to this group picker, follow the instructions and your groups will be picked.")
            groupnum = int(input("How many groups do you want?"))
            peoplenum = int(input("How many people are there?"))
            if groupnum == 'Q':
                sys.exit(0)
            print("Okay, assign everyone a number from 1 to", peoplenum, ".")

            nums = []
            for i in range(1, peoplenum+1):
                nums.append(i)

            ''' Validate number of people vs groups '''
            if peoplenum % groupnum:
                print("error: You have incorrect number of people to divide them equally")
                sys.exit(1)

            ''' People per team '''
            peoplePerTeam = int(peoplenum/groupnum)

            ''' Initialize the group'''
            group = {}
            for i in range(1,groupnum+1):
                group[i] = set()

            ''' Loop through the people'''
            for person in nums:
                while True:
                    ''' Find random team '''
                    randomGroup = random.randint(1,groupnum)

                    ''' If team is not filled up yet, then add otherwise find a new team'''
                    if len(group[randomGroup]) < peoplePerTeam:
                        group[randomGroup].add(person)
                        break

            ''' Display the team info'''    
            for i in range(1,groupnum+1):
                print("Team %s members are %s" %(i, group[i]))

        except:
            print("Error, please follow instructions and enter only numbers.")
            break


main()

该程序输出的示例运行如下:

Welcome to this group picker, follow the 
instructions and your groups will be picked.
How many groups do you want?2
How many people are there?8
Okay, assign everyone a number from 1 to 8 .
**Team 1 members are {1, 2, 5, 7}**
**Team 2 members are {8, 3, 4, 6}**
Welcome to this group picker, follow the 
instructions and your groups will be picked.
How many groups do you want?4
How many people are there?20
Okay, assign everyone a number from 1 to 20 .
**Team 1 members are {1, 18, 19, 20, 17}**
**Team 2 members are {16, 13, 11, 5, 7}**
**Team 3 members are {10, 9, 2, 3, 4}**
**Team 4 members are {8, 12, 15, 6, 14}**
Welcome to this group picker, follow the instructions and your groups will be picked.

答案 5 :(得分:0)

解决方案

import random


def main():
    run = True
    while run:

            print("\nWelcome to this group picker, follow the" \
                "instructions and your groups will be picked.\n")

            group_amount = int(input("How many groups do you want?\n"))
            people_amount = int(input("How many people are there?\n"))

            print("\nOkay, assign everyone a number from 1 to " +
                str(people_amount) + " .\n")

            group = list(range(0, group_amount))
            person = list(range(0, people_amount))
            group_size = people_amount / group_amount


            if group_size % 2 != 0:
                reg_group_size = (people_amount - 1) / group_amount
                odd_group_size = ((people_amount - 1) / group_amount) + 1

            for i in group[0:-1]:
               group[i] = reg_group_size

            group[-1] = odd_group_size

            for p in person:
                r = random.randint(0, len(group)-1)
                while group[r] == 0:
                    r = random.randint(0, len(group)-1) 
                person[p] = r + 1
                group[r] -= 1
                print("Person " + str(p + 1) + " is in group " + 
                    str(person[p]) + ".")

main()

输出

(xenial)vash@localhost:~/pcc/12/alien_invasion_2$ python3 helping.py

Welcome to this group picker, follow theinstructions and your groups will be picked.

How many groups do you want?
3
How many people are there?
10

Okay, assign everyone a number from 1 to 10 .

Person 1 is in group 3.
Person 2 is in group 1.
Person 3 is in group 2.
Person 4 is in group 2.
Person 5 is in group 1.
Person 6 is in group 3.
Person 7 is in group 2.
Person 8 is in group 1.
Person 9 is in group 3.
Person 10 is in group 3.

评论

我同意所有上述解决方案,但是我认为大多数解决方案与您的原始代码有很大的出入。

我试图忠实于您的代码,同时实现了使代码按预期运行并保留原始输出所需的缺失部分。

主要问题是,random.randint值并不能说明将人员分配给一个组后每个组中可用空间的缩小情况。

步骤1:

        group = list(range(0, group_amount))
        person = list(range(0, people_amount))
        group_size = people_amount / group_amount

这将创建一个列表groupperson,它们是各自金额的大小。另外,让我们创建group_size,它将为我们提供每个person中可以包含的group

第2步:

        if group_size % 2 != 0:
            reg_group_size = (people_amount - 1) / group_amount
            odd_group_size = ((people_amount - 1) / group_amount) + 1

        for i in group[0:-1]:
           group[i] = reg_group_size

        group[-1] = odd_group_size

如果group的大小不相等,我们在此解决该问题。这将创建所有大小均匀的group,最后一个group可以保留剩余的person

第3步:

        for p in person:
            r = random.randint(0, len(group)-1)
            while group[r] == 0:
                r = random.randint(0, len(group)-1) 
            person[p] = r + 1
            group[r] -= 1
            print("Person " + str(p + 1) + " is in group " + 
                str(person[p]) + ".")

现在有趣的部分!此循环会将person[p]分配给随机的group,然后将该group的数量减少1。

让我们分解一下:

        for p in person:
            r = random.randint(0, len(group)-1)
            while group[r] == 0:
                r = random.randint(0, len(group)-1)

我们将遍历person来分配所有人口。 然后,我们选择一个随机的group来分配person,但我们要确保group[r]有可用空间,while group[r] == 0:进行检查以确保是否有空间,则会生成一个新的r,直到找到一个有可用空间的随机group为止。

            person[p] = r + 1
            group[r] -= 1
            print("Person " + str(p + 1) + " is in group " + 
                str(person[p]) + ".")

最后,我们给person[p] = r + 1赋予person[p]一个group的数字(使用r + 1是,因此我们可以消除“组0”,因为列表从0开始,对于演示文稿,我们想从1)开始。之后,group[r]的值将减少1,说明可用空间减少了。再次在print语句中,+ 1就是这样,我们再也没有将任何人称为“ Person 0”。

希望这对您有所帮助,我很乐意为此工作!