Esecuzione di una simulazione di allocazione più volte rompe dopo la prima manche
-
04-10-2019 - |
Domanda
Sfondo
Ho un gruppo di studenti, i loro progetti desiderati e provveditori per i rispettivi progetti. Sto correndo una batteria di simulazioni per vedere quali progetti gli studenti finiscono con, che mi permetterà di ottenere alcune statistiche utili necessari per il feedback. Quindi, questo è essenzialmente una simulazione Monte-Carlo
dove sto casualità l'elenco degli studenti e poi l'iterazione attraverso di essa, l'assegnazione di progetti fino a quando mi ha colpito alla fine della lista. Poi il processo si ripete ancora una volta.
Si noti che, all'interno di una singola sessione, dopo ogni attribuzione di un buon progetto i seguenti avvengono:
+ Il progetto è impostato su allocated
e non può essere dato a un altro studente
+ Il supervisore ha un quota
fisso di studenti che possono supervisionare. Questo è decrementato di 1
+ Una volta che il quota
colpisce 0, tutti i progetti di quel supervisore diventare blocked
e questo ha lo stesso effetto di un progetto essendo allocated
Codice
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
Il ruolo di resetData()
è quello di "reset" alcuni bit dei dati. Ad esempio, quando un progetto viene allocata con successo, project.allocated
per quel progetto viene girata True
. Mentre questo è utile per una singola corsa, per la prossima corsa ho bisogno di essere deallocato.
Sopra Sono scorrendo Thee tre dizionari - uno ciascuno per gli studenti, i progetti e le autorità di vigilanza - in cui sono memorizzate le informazioni.
Il bit successivo è la simulazione "Monte-Carlo" per l'algoritmo di allocazione.
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
Tutti randomiseStudents(1)
fa è randomizzare l'ordine di studenti.
Allocated
è una classe definita come tale:
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
Ora, se faccio funzionare questo ottengo un output come questo (troncato):
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)
In pratica, funziona perfettamente per la prima manche, ma su esecuzioni successive che portano fino a n th corsa, in questo caso 50, viene restituita solo una singola coppia di allocazione degli studenti-progetto.
In questo modo, il problema principale Ho problemi con è capire che cosa sta causando questo comportamento anomalo soprattutto perché la prima esecuzione funziona senza problemi.
Grazie in anticipo,
Az
Soluzione
Avete veramente intenzione di impostare quota del supervisore a 0 in resetData()
? Non dire tutti i loro progetti sono ora bloccati?
Disse il corvo:
Il supervisore ha una quota fissa di studenti che possono supervisionare. Questo è decrementato di 1. Quando il contingente colpisce 0, tutti i progetti da tale supervisore ostruirsi e questo ha lo stesso effetto di un progetto alloca.
Se questo non lo è, si dovrebbe verificare l'output di randomiseStudents()
per garantire è la restituzione di un elenco completo. Si tratta, dopo tutto, l'elemento di controllo per tale ciclo interno.
Aggiornamento sulla base di commenti:
Sembra che il problema è stata ??em> che si stavano mettendo quota del supervisore per 0 rendendo in tal modo tutti i loro progetti bloccati.
Questa è pura congettura da parte mia, ma probabilmente ottenuto uno studente in ogni iterazione, perché il controllo di tutte le autorità di vigilanza è accaduto dopo una dotazione. In tal caso, quella appena allocata avrebbe una quota di -1 e tutti gli altri contingenti sarebbe 0, efficace fermandosi tutti allocazioni dopo quello.
L'ideale, che ci si vuole impostare delle quote del supervisore al loro valore originale in resetData()
. Se si trattasse di una quota fissa (lo stesso per ogni autorità di vigilanza), si può semplicemente utilizzare:
for supervisor in supervisors.itervalues():
supervisor.quota = 7 # for example
Se ogni supervisore aveva una quota diversa, si avrebbe bisogno di negozio che insieme alle altre informazioni (durante l'inizializzazione ma non reset) come, per, ad esempio supervisor.start_quota
. Allora si potrebbe utilizzare:
for supervisor in supervisors.itervalues():
supervisor.quota = supervisor.start_quota