Job problema scheduling

voti
8

Sto lavorando a una domanda in cui ho bisogno di pianificare automaticamente posti di lavoro per i membri a rotazione. Non sono molto bravo a spiegare le regole, quindi ecco alcuni dati per dare una mano:

Posizioni: un titolo di lavoro, con una normativa, come il lunedì e il mercoledì settimanali.
Categorie: un insieme di posizioni
Gruppi: Un'altra serie di posizioni. Posizioni dello stesso gruppo non possono essere assegnati lo stesso giorno
Membri: gli utenti assegnati a posizioni su una determinata data.

Per ogni data del mese, i membri vengono assegnati alle posizioni (sia in ordine ascendente). Se un membro è assegnato ad una posizione in una categoria, la prossima volta che una posizione nella stessa categoria viene in su, il prossimo membro in ordine alfabetico (o l'inizio della lista) ottiene per esempio assegnati.

Membri: M1, M2, M3, M4
posizioni nella Categoria C1: P1, P2, P3
membri nella posizione P1: M1, M2, M3, M4
membri nella posizione P2: M1, M2, M3
membri nella posizione P2: M1, M3, M4

Se M1 è assegnato per P1, P2 se viene dopo, verrà assegnato M2. Un ulteriore livello di complessità è introdotto in cui, se P3 viene dopo, invece, M3 viene assegnato. Il sistema deve tenere traccia del fatto che M2 è 'saltato' e assegnare M2 successiva se disponibile, quindi assegnare M4 prossimo, o attendere finché arriva a una posizione in cui M2 è disponibile (questo diventa inoltre complessa quando ci sono molti 'saltato dei membri).

Un membro sarà inoltre saltato se ha indicato che non sarà disponibile in quella data. Il sistema ha bisogno di inserire la priorità sui membri saltati, in qualche modo identificarli quando sono venuti fuori e poi passare alla persona successiva logica nella lista. Skipping vale anche per i gruppi a causa della data scontri.

Ho già una temporanea soluzione [e disordinato], che ho capito non è più anche se ho un sacco di commenti in esso che spiegano ogni passo. Le sue debolezze sono nel trattare con i membri saltati.

Se si dovesse andare a codificare questo come è possibile andare a questo proposito? Sto attuazione del presente in PHP, ma pseudocodice avrebbe funzionato pure.

È pubblicato 19/12/2009 alle 11:20
fonte dall'utente
In altre lingue...                            


3 risposte

voti
1

uff. Non ti seguo descrizione, ma in situazioni simili ho usato SQL per risolvere questo tipo di problema. se si utilizza PHP Credo che si dispone di SQL disponibili.

quello che vorrei suggerire facendo è trovare un modo di memorizzare queste informazioni in un insieme di tabelle e poi capire cosa query SQL che si dà la risposta che si desidera. molto spesso è molto più semplice da fare in SQL quanto lo sia in un linguaggio procedurale.

per la parte saltato, ad esempio, si potrebbe avere una colonna che registra quando qualcuno è entrato l'ultima assegnato, e poi fine da che (in modo che si seleziona la persona che non è stato assegnato per un lungo periodo di tempo). In alternativa, si potrebbe avere il numero di volte saltato come una colonna e l'ordine da questo.

Risposto il 19/12/2009 a 13:09
fonte dall'utente

voti
6

La mia soluzione: Avete bisogno di un CodaConPriorita (che è disponibile in PHP sotto SplPriorityQueue). Il CodaConPriorita ti dà gli elementi con priorità discendente (allineati secondo valori, il valore più piccolo ha la più alta priorità).

Ogni membro ottiene un valore assegnato. Questo valore è un numero ASCII con le cifre n (è possibile utilizzare 8 cifre per comodità), riempiti con zeri a n posizioni. Dopo che si aggiunge il nome. È inoltre aggiungere a ciascun membro delle posizioni disponibili

Così (n = 5):

  • Valore M1: 99999Albert P1, P2, P3
  • Valore M2: 99999Susi P1, P2
  • Valore M3: 99999Bob P1, P3

Ciò rende più semplice per ordinare i membri per priorità e il nome.

Preparazione:

Un giorno soleggiato. Si stanno recuperando le posizioni assegnate e una categoria per un dato giorno. Ogni membro è caricato su una lunga lista. Ogni membro che non sta mostrando sul lavoro non viene caricato, ma viene il suo valore è diminuito di meno due. Bob non è qui, quindi il suo nuovo valore ottiene 99997Bob. Questo significa che Bob verrà selezionato automaticamente la volta successiva. Tutti gli altri membri ottenere il loro valore è diminuito di meno uno.

Le posizioni assegnate per un giorno specifico sono mappati (uso SplObjectStorage):

P1-> M1, M2, M3, M4 ecc P2-> etc.

La mappa contiene solo le posizioni che devono essere assegnati ad oggi. Dopo il

Filtro: È necessario cercare i gruppi ed eliminare tutte le posizioni sulla mappa che non può essere assegnato ad oggi. La vostra descrizione del gruppo è un po 'poco chiaro.

Assegnare:

  • Si sceglie la posizione da assegnare
  • Ottenere l'elenco dei membri che possono riempire la posizione
  • Rimuovere membri disponibili dalla lista e metterli nel CodaConPriorita
  • Assegnare la posizione da estratto () da CodaConPriorita (corretta assegnazione avviene scorrono automaticamente). Ogni membro che viene assegnato volontà prende il suo valore è aumentato di uno (Così i livelli di fuori di aumento e diminuzione se siete qui e di lavoro). Se siete qui e non assegnato ad una posizione per qualsiasi motivo, si ottiene una piccola penalità di un. Se non qui, si ottiene una penalità di due.
  • Dopo il completamento, mettere i membri rimasti in lista di nuovo, deselezionare la PQueue e continuare con il prossimo incarico.

Avvertenze:

  • È necessario fare attenzione che ci sono sempre abbastanza persone per una posizione.
Risposto il 02/01/2010 a 16:10
fonte dall'utente

voti
0

Quello che ho capito è che ci sono membri 'm' e le posizioni 'n'.

Categoria: un gruppo di posizioni - un membro che viene assegnato una posizione nella categoria non può avere un altro?

Gruppo: un gruppo di posizioni - posizioni nello stesso gruppo deve essere assegnato in giorni diversi.

Ultima cosa, una posizione ha una lista di membri che possono riempirlo.

Guardando a questo da un punto di struttura di dati di vista, mettere i membri in una lista concatenata - ogni membro deve avere un ulteriore elenco di [posizione, giorno] che stanno finalmente assegnati. Poi, per ogni posizione, avere una lista di riferimenti ai membri che possono riempire quella posizione. Implementare categorie come un altro elenco di riferimenti per una posizione tale da quali categorie si trova.

L'assegnazione attuale: hanno un contatore al giorno = 0, e iterare attraverso le posizioni. Per ciascuna posizione P, scorrere attraverso i membri che possono riempire esso. Un membro M può riempire la posizione se:

  • Qualsiasi posizione che ha riempito P2 non condivide una categoria con P.
  • Qualsiasi posizione che ha riempito P2 con il giorno = daycounter non condivide un gruppo con P.

Se riesce a riempire la posizione, la [Posizione, giorno] coppia viene aggiunto al membro, e il nodo del membro viene spostato alla fine della lista (questo è il motivo per cui sono necessari i riferimenti - tutti i riferimenti sono ancora validi, anche se il nodo spostato). Ciò assicura che il 'ignorate' membri viene dato massima priorità, ei membri non raggiunti stata data priorità più alta successiva.

Una volta che una posizione è riempita, passare alla posizione successiva. Se la posizione condivide un gruppo con una posizione già assegnato, saltare, scorrendo tutte le posizioni fino a quando è possibile assegnare il maggior numero di posizioni, come si può il giorno 1. Poi, incrementare il contatore giorno e ripetere per il giorno 2. Questo dovrebbe dare un'assegnazione massima (non sono sicuro di massimo) per tutti i lavori.

Suggerimento: quando si sposta un membro alla fine della lista dei membri, per evitare di dover attraversare la lista, mantenere un riferimento alla chiusura - per la posizione successiva, è necessario iniziare dall'inizio comunque, quindi non c'è motivo di passare attraverso l'intera cosa.

Risposto il 02/01/2010 a 18:16
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more