Предыстория
У меня есть группа студентов, их желаемые проекты и руководители соответствующих проектов. Я запускаю серию симуляций, чтобы посмотреть, какие проекты получат студенты, что позволит мне получить полезную статистику, необходимую для обратной связи. Итак, это, по сути, Monte-Carlo
симуляция, в которой я рандомизирую список студентов, а затем перебираю его, распределяя проекты, пока не дойду до конца списка. Затем процесс повторяется снова.
Обратите внимание, что в течение одного сеанса после каждого успешного распределения проекта происходит следующее:
+ проект устанавливается на allocated
и не может быть передан другому студенту
+ у руководителя есть фиксированное quota
студентов, которых он может контролировать. Это значение уменьшается на 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
randomiseStudents()
, что, я подозреваю, как и paxdiablo. - person Justin Peel   schedule 26.05.2010resetData()
, на которую указал paxdiablo. Спасибо за вклад в любом случае. :) - person PizzAzzra   schedule 26.05.2010