python - 根据喜好将一群人分成两半

标签 python combinations split preference

我是一名 3D 动画导师,拥有非常基本的 Python 知识,并且一直在努力编写我认为可能非常有用的脚本。 任何帮助,包括正确方向的简单观点,将不胜感激。提前致谢。

这是我的场景: 我类18名学生即将进入“小组项目”模块。 今年,我想将类(class)分成两半,以使项目更易于管理,并鼓励良性竞争。 学生们已经填写了调查问卷,并给每个学生一个 0 到 5 之间的数字,以表明他们与所有其他学生一起工作的偏好。 我的想法是,我可以使用这些调查以数学方式计算偏好方面的最佳划分。

现在我已经在 CodeSkulptor 中做了一个非常基本的开始 - 一个基于浏览器的 Python 模拟器。 在这个原型(prototype)版本中,我从 4 个样本“学生”开始 - A、B、C 和 D。 每个学生都给出了他们对其他人的看法,为了简单起见,他们对自己的看法都设置为 0,(尽管这很容易是任何值,因为你不能不与自己合作......)

这是我的伪代码:

  1. 创建包含所有学生的空集“学生”,即 [A、B、C、D]

  2. 创建一个空集“组合”,该集合将填充所有可能的组合,即 [((A,B),(C,D)),((A,C),(B, D)),((A,D)(B,C))]

  3. 定义一个类别,其中包含每个学生的偏好信息,一旦确定了所有可能的组合,该信息将用于计算总体“幸福感”/“士气”最高的组合。

  4. 创建一个函数,循环遍历所有可能的组合,将它们作为列表返回,然后添加到组合集中。

  5. (尚未添加)创建一个函数,循环遍历集合“组合”中的所有组合,并根据学生类(class)中存储的偏好计算总体“幸福感”。

  6. (尚未添加)创建一个函数来打印幸福度最高的组合。

在这种情况下,它应该打印:

print"A,B/C,D = 7"

print"A,C/B,D = 10"

print"A,D/B,C = 15"

print"Highest possible split is A,D/B,C with overall happiness of 15!"

我有点不好意思展示 WIP..但它是:

http://www.codeskulptor.org/#user17_EEvOfHGg7AAZt1w_1.py

或者对于那些宁愿留在此页面上的人:

people = set([])
combinations = set([])

class person:
    def __init__(self, name, A = 3, B = 3, C = 3, D = 3):
        self.name = name
        self.A = A
        self.B = B
        self.C = C
        self.D = D

    def get_name(self):
        return self.name

    def get_A(self):
        return self.A

    def get_B(self):
        return self.B

    def get_C(self):
        return self.C

    def get_D(self):
        return self.D    

# make all the possible combinations
#def combine(people):
#combine any 2 given people into a new group

def combinations(iterable, r):
    # combinations('ABCD', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

####[A,B,C,D]
people.add(person("A", 0, 1, 2, 4))
people.add(person("B", 3, 0, 3, 4))
people.add(person("C", 1, 5, 0, 2))
people.add(person("D", 3, 3, 2, 0))

combinations(people,2)

组合功能 - 我实际上直接从 itertools 文档页面中提取出来,但我不确定它是否有效,或者即使这是拆分组的最佳方法。 我无法直接导入 itertools,因为 CodeSkulptor 仅支持几个模块(数学、随机、时间等)。 我尝试使用实际的Python,但它的功能与我习惯的有很大不同。 我在研究中学到了很多东西,比如计算这样的事情可能需要数年时间,计算机才能经历 24310 种不同的 split 可能性。 另一种选择是让代码一次生成 100 个随机分割可能性,这样我就可以跟踪每次运行的最高结果。 总而言之,这是一个值得尝试和弄清楚的有趣脚本 - 实际上有点太有趣了。 尽管我已经停止取得实际进展,但我无法从 body 上摆脱它。 所以,如果有人可以提示/告诉我从这里该去哪里,我将非常感谢您的帮助。

干杯,

  • 伊莱

最佳答案

已完成

from itertools import combinations
import numpy as np
import string

    def get_maxhappiness(results):
        max_happiness = max(results)
        index = results.index(max_happiness)
    
        #Printing the result! (There may be more than one best result, but this will only show 1)
        print "Optimal Groups: Point value of",max_happiness,"\n",groups[index],"\n", anti_groups[index]
        results[index] = 0
        return results

def calculateHappiness(points,group):
    happiness = 0
    for i in range(len(group)):
        person_prefs = points[group[i]]
        others = group[i:] + group[:i]
        for other in others:
            happiness += person_prefs[other]
    return happiness



if __name__ == "__main__":
    people = string.letters[26:44]
    groups = list(combinations(people,9))
    anti_groups = [tuple(set(people).difference(set(x))) for x in groups]

    #Making fake results
    survey_results = dict()
    for person in people:
        results = dict(zip(people,np.random.randint(0,10,size=(len(people)))))
        results[person] = 0
        survey_results[person] = results

    #Printing Survey Results
    for name,values in survey_results.items():
        print "Student:", name, "has preferences:", values

    #Calculating happiness for every group
    results = []
    for i in range(len(groups)):
        results.append(calculateHappiness(survey_results,groups[i])+calculateHappiness(survey_results,anti_groups[i]))
    #Finding the largest happiness value
    top_n = 5
    while top_n > 0:
        results = get_maxhappiness(results)
        top_n -= 1

产量:

...

Student: N has preferences: {'A': 5, 'C': 5, 'B': 0, 'E': 0, 'D': 3, 'G': 6, 'F'
: 8, 'I': 8, 'H': 3, 'K': 1, 'J': 4, 'M': 4, 'L': 9, 'O': 0, 'N': 0, 'Q': 3, 'P'
: 2, 'R': 2}
Student: Q has preferences: {'A': 9, 'C': 0, 'B': 3, 'E': 4, 'D': 3, 'G': 2, 'F'
: 2, 'I': 7, 'H': 5, 'K': 2, 'J': 3, 'M': 0, 'L': 9, 'O': 2, 'N': 5, 'Q': 0, 'P'
: 2, 'R': 0}
Student: P has preferences: {'A': 2, 'C': 3, 'B': 0, 'E': 9, 'D': 3, 'G': 6, 'F'
: 7, 'I': 1, 'H': 7, 'K': 9, 'J': 7, 'M': 4, 'L': 8, 'O': 2, 'N': 6, 'Q': 5, 'P'
: 0, 'R': 7}
Student: R has preferences: {'A': 5, 'C': 3, 'B': 7, 'E': 1, 'D': 5, 'G': 6, 'F'
: 1, 'I': 6, 'H': 9, 'K': 9, 'J': 3, 'M': 6, 'L': 8, 'O': 8, 'N': 5, 'Q': 1, 'P'
: 3, 'R': 0}
Optimal Groups: Point value of 709
('A', 'B', 'F', 'G', 'J', 'K', 'O', 'Q', 'R')
('C', 'E', 'D', 'I', 'H', 'M', 'L', 'N', 'P')
(x4)

关于python - 根据喜好将一群人分成两半,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18039067/

相关文章:

python - GCC 插件、GCC Melt 或 gcc Python 插件来编写 gcc 扩展

c++ - 编码比赛 : How to store large numbers and find its all combination modulus P

java - 拆分字符串并用标点符号和空格分隔

r - 当我拆分列表中的data.frame时,如何使输出更加优雅?

python - 处理对象而不是模块重新加载的最佳方法

python - 使用 pymongo 向 mongoDB 中插入数据

python - 如何忽略配置单元插入查询中输入的开始

algorithm - 查找给定 n 个键的二叉树数量的变体

c++ - C++中M个盒子中N个球的组合列表

php - 拆分导入 CSV 到 mysql 数据库受限