Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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中从长度为n的列表中获取n*k个2的唯一集_Python_List_Algorithm_Set - Fatal编程技术网

在Python中从长度为n的列表中获取n*k个2的唯一集

在Python中从长度为n的列表中获取n*k个2的唯一集,python,list,algorithm,set,Python,List,Algorithm,Set,我有一个Python难题:我们安排了一个有48名参与者的30天计划。在该计划中,参与者每天都是两人一组。参与者不能有两次相同的伙伴,所有参与者必须每天结成伙伴。另外,我希望我的数学在标题中是正确的 我管理了一个实现,但感觉很笨拙。有没有一种有效的方法可以做到这一点?也许以某种方式使用笛卡尔积?非常感谢所有反馈和提示 # list of people: 48 # list of days: 30 # each day, the people need to be split into pairs

我有一个Python难题:我们安排了一个有48名参与者的30天计划。在该计划中,参与者每天都是两人一组。参与者不能有两次相同的伙伴,所有参与者必须每天结成伙伴。另外,我希望我的数学在标题中是正确的

我管理了一个实现,但感觉很笨拙。有没有一种有效的方法可以做到这一点?也许以某种方式使用笛卡尔积?非常感谢所有反馈和提示

# list of people: 48
# list of days: 30
# each day, the people need to be split into pairs of two.
# the same pair cannot occur twice

import random
from collections import Counter

class person ():

    def __init__ (self, id):
        self.id = id


class schedule ():

    def __init__ (self, days):
        self.people_list = []
        self.days = days
        self.placed_people = []
        self.sets = []


    def create_people_list(self, rangex):

        for id in range(rangex): 
            new_person = person(id)
            self.people_list.append(new_person) 

        print(f"{len(self.people_list)} people and {self.days} days will be considered.")


    def assign_pairs(self):


        for day in range(self.days): # for each of the 30 days..
 
            print("-" * 80)
            print(f"DAY {day + 1}") 

            self.placed_people = [] # we set a new list to contain ids of placed people

            
            while Counter([pers.id for pers in self.people_list]) != Counter(self.placed_people):

                pool = list( set([pers.id for pers in self.people_list]) - set(self.placed_people))
                # print(pool)

                person_id = random.choice(pool) # pick random person
                person2_id = random.choice(pool) # pick random person

                    
                if person_id == person2_id: continue 

                if not set([person_id, person2_id]) in self.sets or len(pool) == 2:
                    
                    if len(pool) == 2: person_id, person2_id = pool[0], pool[1]

                    self.sets.append(set([person_id, person2_id]) )
                    self.placed_people.append(person_id)
                    self.placed_people.append(person2_id)

                    print(f"{person_id} {person2_id}, ", end="")

schdl = schedule(30) # initiate schedule with 30 days
schdl.create_people_list(48)
schdl.assign_pairs()
产出:

48 people and 30 days will be considered.

--------------------------------------------------------------------------------
DAY 1
37 40, 34 4, 1 46, 13 39, 12 35, 18 33, 25 24, 23 31, 17 42, 32 19, 36 0, 11 9, 7 45, 10 21, 44 43, 29 41, 38 16, 15 22, 2 20, 26 47, 30 28, 3 8, 6 27, 5 14,

--------------------------------------------------------------------------------
DAY 2
42 28, 25 15, 6 17, 2 14, 7 40, 11 4, 22 37, 33 20, 0 16, 3 39, 19 47, 46 24, 12 27, 26 1, 34 10, 45 8, 23 13, 32 41, 9 29, 44 31, 30 5, 38 18, 43 21, 35 36,

--------------------------------------------------------------------------------
DAY 3
8 28, 33 12, 40 26, 5 35, 13 31, 29 43, 44 21, 11 30, 1 7, 34 2, 47 45, 46 17, 4 23, 32 15, 14 22, 36 42, 16 41, 37 19, 38 3, 20 6, 10 0, 24 9, 27 25, 18 39,

--------------------------------------------------------------------------------

[...]

--------------------------------------------------------------------------------
DAY 29
4 18, 38 28, 24 22, 23 33, 9 41, 40 20, 26 39, 2 42, 15 10, 12 21, 11 45, 46 7, 35 27, 29 36, 3 31, 19 6, 47 32, 25 43, 13 44, 1 37, 14 0, 16 17, 30 34, 8 5,

--------------------------------------------------------------------------------
DAY 30
17 31, 25 7, 6 10, 35 9, 41 4, 16 40, 47 43, 39 36, 19 44, 23 11, 13 29, 21 46, 32 34, 12 5, 26 14, 15 0, 28 24, 2 37, 8 22, 27 38, 45 18, 3 20, 1 33, 42 30,
谢谢你的时间!此外,还有一个后续问题:我如何计算是否有可能解决该任务,即每天将所有参与者安排成唯一的一对?

现实生活中的循环赛 非常容易组织。事实上,这个算法非常简单,你可以在没有任何纸张或计算机的情况下组织人与人之间的循环赛,只需给人简单的指令

你有一个偶数
N=48
人类配对。假设你有一张长桌子,一边有
N//2个
座位,另一边面对
N//2个
座位。请所有人坐在那张桌子旁

这是你的第一对

叫其中一个座位“1号座位”

移动到下一对:1号座位上的人不移动。每隔一个人在桌子周围顺时针移动一个座位

Current pairing
1 2 3 4
8 7 6 5

Next pairing
1 8 2 3
7 6 5 4
python中的循环赛
#表格是人类的简单列表
def next_表格(表格):
返回[表[0]]+[表[-1]]+表[1:-1]
# [0 1 2 3 4 5 6 7] -> [0 7 1 2 3 4 5 6]
#配对是一组成对的人
def配对表(表)中的def配对表:
返回列表(zip(表[:len(表)//2],表[-1:len(表)//2-1:-1]))
# [0 1 2 3 4 5 6 7] -> [(0,7), (1,6), (2,5), (3,4)]
#人是一种智力
def get_计划(计划长度、参与人数):
表=列表(范围(参与人数))
配对列表=[]
范围内的日期(节目长度):
配对列表。追加(配对表格(表格))
表=下一个表(表)
返回配对列表
打印(获取计划(3,8))
# [[(0, 7), (1, 6), (2, 5), (3, 4)],
#  [(0, 6), (7, 5), (1, 4), (2, 3)],
#  [(0, 5), (6, 4), (7, 3), (1, 2)]]
打印(获取计划(30、48))
如果希望人是自定义对象而不是整数,可以直接用列表
替换第二个参数
number\u participants
;然后用户可以提供他们想要的任何内容的列表:

def get_程序(程序长度,表格):
配对列表=[]
范围内的日期(节目长度):
配对列表。追加(配对表格(表格))
表=下一个表(表)
返回配对列表
打印(获取计划(3,['Alice','Boubakar','Chen','Damian']))
#[[('Alice','Damian'),('Boubakar','Chen'),
#[('Alice','Chen'),('Damian','Boubakar'),
#[('Alice'、'Boubakar')、('Chen'、'Damian')]]
后续问题:何时存在解决方案? 如果存在
N
人,则每个人都可以与
N-1
不同的人配对。如果
N
为偶数,则循环循环法将确保第一轮
N-1
是正确的。之后,算法是周期性的:第
N
轮将与第一轮相同

因此,当且仅当
节目长度
且参与者人数为偶数时,才有一个解决方案;在这种情况下,循环算法将找到一个解决方案

如果参与者的数量是奇数,那么在计划的每一天,必须至少有一个人没有配对。循环赛仍然可以应用于这种情况:添加一个额外的“虚拟”人(通常称为)。就算法而言,虚拟人的行为与正常人完全相同。每一轮,一个不同的真人将与虚拟人配对,这意味着这一轮他们不会与真人配对。使用这种方法,您只需在现实生活中进行
节目长度的循环赛
非常容易组织。事实上,这个算法非常简单,你可以在没有任何纸张或计算机的情况下组织人与人之间的循环赛,只需给人简单的指令

你有一个偶数
N=48
人类配对。假设你有一张长桌子,一边有
N//2个
座位,另一边面对
N//2个
座位。请所有人坐在那张桌子旁

这是你的第一对

叫其中一个座位“1号座位”

移动到下一对:1号座位上的人不移动。每隔一个人在桌子周围顺时针移动一个座位

Current pairing
1 2 3 4
8 7 6 5

Next pairing
1 8 2 3
7 6 5 4
python中的循环赛
#表格是人类的简单列表
def next_表格(表格):
返回[表[0]]+[表[-1]]+表[1:-1]
# [0 1 2 3 4 5 6 7] -> [0 7 1 2 3 4 5 6]
#配对是一组成对的人
def配对表(表)中的def配对表:
返回列表(zip(表[:len(表)//2],表[-1:len(表)//2-1:-1]))
# [0 1 2 3 4 5 6 7] -> [(0,7), (1,6), (2,5), (3,4)]
#人是一种智力
def get_计划(计划长度、参与人数):
表=列表(范围(参与人数))
配对列表=[]
范围内的日期(节目长度):
配对列表。追加(配对表格(表格))
表=下一个表(表)
返回配对列表
打印(获取计划(3,8))
# [[(0, 7), (1, 6), (2, 5), (3, 4)],
#  [(0, 6), (7, 5), (1, 4), (2, 3)],
#  [(0, 5), (6, 4), (7, 3), (1, 2)]]
打印(获取计划(30、48))
如果希望人是自定义对象而不是整数,可以直接用列表
替换第二个参数
number\u participants
;然后用户可以提供他们想要的任何内容的列表:

def get_程序(程序长度,表格):
配对列表=[]
范围内的日期(节目长度):
配对列表