Esecuzione di una simulazione di allocazione più volte rompe dopo la prima manche

StackOverflow https://stackoverflow.com/questions/2910240

  •  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

È stato utile?

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 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top