Scopri chi è il turno di acquistare i cornetti


9

Una squadra ha deciso che ogni mattina qualcuno dovrebbe portare cornetti per tutti. Non dovrebbe essere sempre la stessa persona, quindi dovrebbe esserci un sistema per determinare di chi è il turno successivo. Lo scopo di questa domanda è determinare un algoritmo per decidere chi sarà il turno di portare i cornetti domani.

Vincoli, ipotesi e obiettivi:

  • Di chi è il turno di portare i cornetti sarà determinato il pomeriggio precedente.
  • In un dato giorno, alcune persone sono assenti. L'algoritmo deve scegliere qualcuno che sarà presente quel giorno. Supponiamo che tutte le assenze siano note con un giorno di anticipo, quindi l'acquirente di cornetti può essere determinato il pomeriggio precedente.
  • Nel complesso, la maggior parte delle persone è presente nella maggior parte dei giorni.
  • Nell'interesse dell'equità, tutti dovrebbero comprare i croissant tante volte quanto gli altri. (Fondamentalmente, supponi che ogni membro del team abbia la stessa quantità di denaro da spendere per i croissant.)
  • Sarebbe bello avere qualche elemento di casualità, o almeno la casualità percepita, al fine di alleviare la noia di un elenco. Questo non è un vincolo difficile: è più un giudizio estetico. Tuttavia, la stessa persona non dovrebbe essere scelta due volte di seguito.
  • La persona che porta i cornetti dovrebbe sapere in anticipo. Quindi, se la persona P deve portare cornetti il ​​giorno D, allora questo fatto dovrebbe essere determinato in un giorno precedente in cui la persona P è presente. Ad esempio, se il cornetto per cornetti viene sempre determinato il giorno prima, dovrebbe essere una delle persone presenti il ​​giorno prima.
  • Il numero dei membri del team è abbastanza piccolo che le risorse di archiviazione e elaborazione sono effettivamente illimitate. Ad esempio l'algoritmo può fare affidamento su una storia completa di chi ha portato i cornetti in passato. Fino a pochi minuti di calcolo su un PC veloce ogni giorno andrebbero bene.

Questo è un modello di un problema del mondo reale, quindi sei libero di sfidare o affinare le ipotesi se pensi che modellino meglio lo scenario.

Origine: Scopri chi acquisterà i cornetti di Florian Margaine . La mia riformulazione qui ha requisiti leggermente diversi.


1
Qual era esattamente la domanda? Possiamo presumere che le persone siano assenti più o meno lo stesso importo? Cosa c'è di sbagliato nel prendere la persona che l'ha fatto il minor numero di volte, o semplicemente una persona a caso?
Pål GD,

@ PålGD Supporre che le persone siano assenti di circa lo stesso importo sarebbe una semplificazione. Fallo se vuoi, ma se il tuo algoritmo funziona per i part-time, è meglio. Prendendo la persona che lo ha fatto il minor numero di volte è una soluzione (anche se tenete presente il requisito che conoscono con un giorno di anticipo, la soluzione non è del tutto banale). Anche una persona a caso può lavorare, ma la casualità introduce una deviazione dall'equità che potresti voler limitare.
Gilles 'SO- smetti di essere malvagio' il

Che cosa? Nessuna immagine salivare? Vuoi che siamo schiavi della nostra scrivania a fare matematica invece di sgattaiolare fuori al forno?
Caleb,

@Gilles - Cordiali saluti, eseguendo un esperimento su P.SE con la tua versione di questa domanda . Ora che entrambi i siti sono un po 'più vecchi, sono curioso di vedere come si formano le risposte di ogni comunità.

Risposte:


7

Sono a conoscenza di due categorie di soluzioni a questo tipo di problema: lotterie distorte e sequenze casuali filtrate / generate .

Per prima cosa, rinunciamo a soluzioni semplici ma sbagliate che non mantengono alcuno stato. Qualsiasi soluzione in stile lotteria che non mantiene alcuno stato avrà il numero di vincite in una distribuzione binomiale, che non soddisfa il criterio "tante volte". Puoi selezionare una sequenza casuale che seleziona tutte le persone allo stesso modo (semplicemente andando in giro nell'elenco; le permutazioni forniscono casualità), ma una volta che le persone iniziano a andare in vacanza, la sequenza ora ha buchi. A meno che tu non tenga traccia, ti ritroverai di nuovo con le distribuzioni binomiali invece di mantenere lo stesso sforzo.

Impegniamoci anche ad avere una casualità effettiva. Potresti desiderarlo in modo che, ad esempio, una persona non possa programmare la propria vacanza sulla base di un algoritmo deterministico in modo che non siano mai presenti quando è il suo turno di acquistare croissant (fino a quando non esauriscono tutti i loro giorni di vacanza, suppongo) .

Quindi, sui due tipi di soluzioni.

  1. Per costruire una lotteria di parte, prima nota che possiamo scegliere praticamente da qualsiasi distribuzione continua (con deviazione finita) per generare numeri per la nostra lotteria. Il perdente può quindi essere la persona con il numero più basso. Quindi il pregiudizio più semplice è tenere traccia del fatto che ogni individuo abbia acquistato più o meno della propria quota. È possibile misurare la distorsione in unità di cornetti. Puoi regolare il grado di casualità cambiando la larghezza e la forma della distribuzione - questo determinerà anche quanto lontano un individuo può arrivare "dallo stesso numero di volte". I gaussiani sono facili; consentono una ragionevole sorpresa senza code troppo lunghe ("ingiuste"). Quindi la forma di base della soluzione è (nel codice Scala)

    case class Employee(var bias: Double) {
      def eat         { bias -= 1 }
      def buy(n: Int) { bias += n }
      def roll        = bias + stdev * Random.nextGaussian
    }
    

    Puoi tenere traccia di chi ha acquistato per ultimo e dare loro un forte bonus di pregiudizio (ad es. 10*stdev) Per impedire alle persone di acquistare due volte di seguito salvo nel caso limite in cui la struttura delle vacanze ha permesso a tutti di aver acquistato "l'ultima" volta. (vale a dire che acquisti, poi vai in vacanza.) Stessa cosa per non essere presente il giorno in cui sono stati selezionati. (Se qualcuno è assente a giorni alterni alla fine si presenteranno mentre bruciano il loro bonus di pregiudizio; lo considero una caratteristica piuttosto che un bug.)

    Quindi, raccogli il tuo elenco di dipendenti attuali per la giornata, li fai tutti lanciare per la lotteria, scegli il più basso e aggiorna. Puoi scegliere se avere il bonus d'acquisto uguale al numero di dipendenti (buono quando il costo è trascurabile ma il viaggio per ottenere i cornetti è oneroso), il numero di dipendenti presenti (buono se il viaggio è facile ma il costo è oneroso ) o qualcosa nel mezzo (per riconoscere entrambi gli oneri). Probabilmente è meglio avere la penalità "mangia" solo per le persone presenti, ma puoi farlo in entrambi i modi se ritieni che il semplice fatto di essere in vacanza non ti dia il giusto passo in meno.

  2. Per costruire una sequenza casuale filtrata, devi prima generare una sequenza casuale. Mescolare un elenco dei dipendenti è un buon modo per iniziare. Basta scorrere l'elenco, in ordine, di giorno in giorno. Se qualcuno non può acquistare perché è assente o non può essere detto o acquistato prima, saltalo. Ora hai un problema: stai accumulando persone che sono state saltate. Va bene, però. Quando arrivi alla fine della sequenza, aggiungi l'elenco dei dipendenti saltati all'elenco completo prima di mescolarli. Ora la probabilità di risalire è proporzionale al numero di volte che sei stato saltato, il che mantiene la proprietà "stesso numero di volte".

    Se si utilizza uno shuffle standard, è anche particolarmente facile quantificare la casualità quando non ci sono vacanze. Se hai scelto le persone completamente a caso, la conoscenza di chi doveva essere il prossimo conterrebbe bit di informazioni se ci fossero dipendenti. Invece, invece, soloinvece di sono consentite sequenze possibili, quindi le informazioni sono ridotte di bit (per grande ; per è ).log2(N)NN!NNlog2[(N!NN)1/N]1log(2)+log22π/NN1.4NN=10 1.14

Personalmente preferisco la soluzione di lotteria distorta in quanto il controllo sulla casualità è migliore. Con le sequenze filtrate, puoi trovare modi più complessi per generare sequenze. Ad esempio, anziché prendere una permutazione casuale, eseguire scambi locali a una certa distanza o consentire lo scambio totale di persone fuori dalla piscina (ma vanno nella lista saltata), ma queste cose richiedono più sforzo algoritmico. Con la lotteria, basta regolare la deviazione standard.


4

{P1,...,Pn}vik1Pik10

Per alcuni parametri , lascia .v k = n i = 1 ( v i k ) llvk=i=1n(vik)l

Al giorno , scelgono l'acquirente del croissant del giorno successivo sparando una variabile casuale che risulta con probabilità . Se il prescelto non è qui (oggi o il giorno dopo) gettano di nuovo la moneta fino a quando non ne trovano una adatta (esiste, perché sono per lo più qui ogni giorno ...).i 1 - ( v k i ) lki1(vik)lvk

E vissero felici fino a quando non che , quel codardo, era lì, solo un giorno su due, e così, non compra mai alcun croissant!P1

Dopo qualche riflessione (e potrebbe essere un po 'di tortura suP1

v

vikkvk

Pi

Pik+1kPjPj

Pivik

E quando questo va per sempre, vivono felici, condividendo equamente il prezzo del cornetto.

P1lll=kl

P1P2

P1vik

Ps: scusami per il cattivo inglese ma non sono madrelingua ed è tardi ... per favore sentiti libero di correggere gli errori (e potresti aggiungere spezie alla storia ...)


2

Ogni iterazione che hai

  • Un elenco di persone presenti e disponibili per l'acquisto
  • L'acquirente precedente

Se scegli una persona a caso tra le persone nell'elenco e escludi l'acquirente precedente, raggiungi i tuoi obiettivi:

  1. L'algoritmo è "massimamente" casuale poiché utilizziamo la quantità minima di informazioni della precedente iterazione e scegliamo a caso.
  2. In media le persone pagano per (N / (N-1)) cornetti ogni volta che partecipano a un'estrazione rendendo l'algoritmo il più equo possibile.
  3. Suggerirei di eliminare la regola di non ripetizione per renderla al massimo casuale.

Altri algoritmi che ho visto proposti sono meno casuali o meno equi:

  1. Gli algoritmi "Deck shuffle" non sono realmente casuali, nel senso che la probabilità di dover pagare non è costante (1 / N nella prima scelta, 1 / (N-1) nella seconda ... 1 alla nona scelta - - se uno non è stato ancora scelto). Inoltre, se vieni scelto per primo, hai esattamente zero possibilità di essere scelto per le successive N volte. Il sistema si rompe facilmente entrando raramente fino a quando non viene raccolto e quindi costantemente.

  2. Gli algoritmi "compensativi" che cercano di far attivamente ottenere a tutti lo stesso numero di cornetti invece di fare affidamento sulle proprietà dei numeri casuali non riescono a essere casuali o equi (o entrambi).


NmN/m1

N

@RexKerr perché dovresti comprare più cornetti che dipendenti?
Sklivvz,

Non ho capito bene. Dove ho suggerito di farlo?
Rex Kerr,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.