背景
我有很多学生,他们所需的项目和各自项目的主管。我正在运行一系列模拟,以查看学生最终完成的项目,这将使我获得反馈所需的一些有用的统计信息。因此,这本质上是 Monte-Carlo 我要在其中随机绘制学生列表,然后遍历它,然后分配项目,直到我达到列表的结尾为止。然后再次重复该过程。

请注意,在一次会话中,每次成功分配项目后,都会进行以下内容:
+该项目设置为 allocated 不能给另一个学生
+主管有固定的 quota 他可以监督的学生。这被1减少了1
+一次 quota 命中0,该主管的所有项目都成为 blocked 这与项目的效果相同 allocated

代码

def resetData():
    for student in students.itervalues():
        student.allocated_project = None

    for supervisor in supervisors.itervalues():
        supervisor.quota = 0

    for project in projects.itervalues():
        project.allocated = False
        project.blocked = False

的作用 resetData() 是“重置”数据的某些位。例如,当项目成功分配时, project.allocated 因为该项目被翻转为 True. 。虽然这对于一次运行很有用,但对于下一次运行,我需要被划分。

在上面,我要迭代三个词典 - 每个词典,每个词典,每个词典,每个词典,项目和主管 - 存储信息的位置。

下一点是分配算法的“蒙特卡洛”模拟。

sesh_id = 1

for trial in range(50):

    for id in randomiseStudents(1):
        stud_id = id
        student = students[id]
        if not student.preferences:
        # Ignoring the students who've not entered any preferences

            for rank in ranks:
                temp_proj = random.choice(list(student.preferences[rank]))

                if not (temp_proj.allocated or temp_proj.blocked):
                    alloc_proj = student.allocated_proj_ref = temp_proj.proj_id
                    alloc_proj_rank = student.allocated_rank = rank
                    successActions(temp_proj)
                    temp_alloc = Allocated(sesh_id, stud_id, alloc_proj, alloc_proj_rank)
                    print temp_alloc # Explained
                    break                  
    sesh_id += 1
    resetData()  # Refer to def resetData() above

全部 randomiseStudents(1) 确实是随机的学生的顺序。

Allocated 是这样定义的类:

class Allocated(object):
    def __init__(self, sesh_id, stud_id, alloc_proj, alloc_proj_rank):
        self.sesh_id = sesh_id
        self.stud_id = stud_id
        self.alloc_proj = alloc_proj
        self.alloc_proj_rank = alloc_proj_rank

   def __repr__(self):
        return str(self)

   def __str__(self):
        return "%s - Student: %s (Project: %s - Rank: %s)" %(self.sesh_id, self.stud_id, self.alloc_proj, self.alloc_proj_rank)

Output and problem

现在,如果我运行此操作,我会得到这样的输出(截断):

1 - Student: 7720 (Project: 1100241 - Rank: 1)
1 - Student: 7832 (Project: 1100339 - Rank: 1)
1 - Student: 7743 (Project: 1100359 - Rank: 1)
1 - Student: 7820 (Project: 1100261 - Rank: 2)
1 - Student: 7829 (Project: 1100270 - Rank: 1)
.
.
.
1 - Student: 7822 (Project: 1100280 - Rank: 1)
1 - Student: 7792 (Project: 1100141 - Rank: 7)
2 - Student: 7739 (Project: 1100267 - Rank: 1)
3 - Student: 7806 (Project: 1100272 - Rank: 1)
.
.
.
45 - Student: 7806 (Project: 1100272 - Rank: 1)
46 - Student: 7714 (Project: 1100317 - Rank: 1)
47 - Student: 7930 (Project: 1100343 - Rank: 1)
48 - Student: 7757 (Project: 1100358 - Rank: 1)
49 - Student: 7759 (Project: 1100269 - Rank: 1)
50 - Student: 7778 (Project: 1100301 - Rank: 1)

基本上,它适用于第一次运行,但在随后的运行中 n在这种情况下,运行50,只返回了一个学生项目分配对。

因此,我遇到的主要问题是弄清楚导致这种异常行为的原因,尤其是因为第一次运行顺利进行。

提前致谢,

AZ

有帮助吗?

解决方案

您是否真的打算将主管的配额设置为0 resetData()?这是否意味着他们的所有项目现在都被封锁了?

乌鸦quoth:

主管有一个可以监督的学生的固定配额。这将减少1。一旦配额达到0,该主管的所有项目都会被阻塞,这与分配的项目相同。

如果不是这样,您应该检查 randomiseStudents() 确保它返回完整列表。毕竟,它是该内部循环的控制项目。


根据评论的更新:

看来问题 曾是 您将主管的配额设置为0,从而使他们的所有项目被阻止。

这对我来说是纯粹的猜测工作,但是您可能会在每次迭代中都有一个学生,因为对所有主管的检查发生在分配后。在这种情况下,只有一个刚分配的配额为-1,所有其他配额将为0,有效地停止 全部 在那之后分配。

理想情况下,您想将主管的配额设置为原始价值 resetData(). 。如果是固定的配额(每个主管相同),则可以简单地使用:

for supervisor in supervisors.itervalues():
    supervisor.quota = 7 # for example

如果每个主管有不同的配额,则需要将其与其他信息一起存储(在初始化期间但不重置),例如,例如 supervisor.start_quota. 。然后您可以使用:

for supervisor in supervisors.itervalues():
    supervisor.quota = supervisor.start_quota
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top