problemă de programare de locuri de muncă

voturi
8

Lucrez la o cerere în cazul în care am nevoie pentru a programa în mod automat de locuri de muncă pentru membrii pe un program de rotație. Nu sunt foarte bun la a explica regulile, deci iată câteva date pentru a ajuta:

Pozitii: Un titlu loc de muncă, cu reguli , cum ar fi zilele de luni și miercuri săptămânale.
Categorii: Un set de poziții
grupuri: Un alt set de poziții. Pozițiile din același grup nu pot fi atribuite în aceeași zi ,
membrii: Utilizatorii desemnați în funcții la o anumită dată.

Pentru fiecare dată în luna, membrii sunt atribuite poziții (atât în ​​ordine crescătoare). În cazul în care un membru este atribuit într-o poziție într-o singură categorie, data viitoare o poziție în aceeași categorie vine, următorul membru în ordine alfabetică (sau la începutul listei) devine de exemplu atribuit.

Membrii: M1, M2, M3, M4
Pozițiile în Categoria C1: P1, P2, P3
Membrii în poziția P1: M1, M2, M3, M4
membri în poziția P2: M1, M2, M3
Membrii în poziția P2: M1, M3, M4

În cazul în care M1 este alocat pentru P1, P2 dacă vine următoarea, M2 va fi atribuit. Un strat suplimentar de complexitate este introdus în cazul în care în cazul în care P3 vine în locul următor, M3 se atribuie. Sistemul trebuie să țină evidența faptul că M2 a fost „sărit“ și alocați M2 următoare dacă este disponibilă, apoi atribuiți M4 următor sau așteptați până când ajunge într-o poziție în care M2 este disponibil (acest lucru devine suplimentar complex, atunci când există mai multe „omit membri).

Un membru va fi, de asemenea, omisă în cazul în care a indicat că nu va fi disponibilă la acea dată. Sistemul trebuie să se plaseze prioritate asupra membrilor omit, într-un fel le identifica atunci când vin în sus și apoi să sară la următoarea persoană logică din listă. Omiterea se aplică și grupurilor din cauza datei de ciocniri.

Am deja o temporară [și murdar] soluție pe care eu nu mai înțeleg, chiar dacă am o mulțime de comentarii în ea explicând fiecare pas. punctele slabe ale acestuia, în care se ocupă cu membrii omit.

Dacă ai de gând să cod acest lucru cum ar merge despre asta? Sunt de punere în aplicare acest lucru în PHP, dar pseudocod ar funcționa la fel de bine.

Întrebat 19/12/2009 la 11:20
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
1

Uff. Eu nu urmați descrierea, dar în situații similare i-au folosit pentru a rezolva sql acest tip de problemă. dacă utilizați php Cred că aveți sql disponibile.

ceea ce ar sugera face este de a găsi o modalitate de stocare a acestor informații într-un set de tabele și apoi de lucru ce interogare SQL vă oferă răspunsul dorit. destul de des este mult mai simplu de făcut în sql decât este într-o limbă de procedură.

pentru partea omit, de exemplu, este posibil să aveți o coloană care înregistrează atunci când cineva a fost ultima atribuit, și apoi comanda care (astfel încât să selectați persoana care nu a fost atribuit pentru o lungă perioadă de timp). În mod alternativ, ai putea avea numărul de ori omit ca o coloană și ordinea de asta.

Publicat 19/12/2009 la 13:09
sursa de către utilizator

voturi
6

Soluția mea: Ai nevoie de o coadă prioritară (care este disponibil în PHP sub SplPriorityQueue). Vă oferă elemente de coadă prioritară cu prioritate descrescătoare (sortate de valori, cea mai mică valoare are cea mai mare prioritate).

Fiecare membru primește o valoare atribuită. Această valoare este un număr ASCII cu n cifre (ai putea folosi 8 cifre pentru comoditate), completate cu zerouri la n poziții. După aceea vă adăugați numele. De asemenea, puteți adăuga la fiecare membru pozițiile disponibile

Deci, (n = 5):

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

Acest lucru îl face ușor pentru a sorta membrilor după prioritate și nume.

Mod de preparare:

O zi insorita. Tu Preluăm pozițiile atribuite și o categorie pentru o anumită zi. Fiecare membru este încărcat pe o listă lungă. Fiecare membru care nu apare pe locul de muncă nu este încărcată, dar devine valoarea lui a scăzut cu minus doi. Bob nu este aici, asa ca noua sa valoare devine 99997Bob. Acest lucru înseamnă că Bob va fi selectat automat data viitoare. Toți ceilalți membri ai obține valoarea lor a scăzut cu un minus.

Pozițiile alocate pentru o anumită zi sunt mapate (utilizarea SplObjectStorage):

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

Harta conține numai pozițiile care trebuie să fie atribuite în această zi. După

Filtru: Trebuie să priviți în sus grupurile și șterge orice poziții de pe hartă, care nu pot fi atribuite în această zi. Descrierea dvs. de grup este un pic neclar.

Atribui:

  • Puteți alege poziția de a atribui
  • Obține lista de membri, care pot umple poziția
  • Eliminați membri disponibile din listă și le-a pus în coadă prioritară
  • Asociați poziția de extract () din coadă prioritară (repartizare corectă se face automaticially). Fiecare membru care este atribuit voința devine valoarea sa a crescut cu unul (deci nivelurile reduce cât și crește dacă sunteți aici și de lucru). Dacă sunteți aici și nu sunt atribuite unei poziții pentru orice motiv, veți obține o pedeapsă mică de unu. Dacă nu aici, veți obține o penalizare de două.
  • După finalizare, a pus membrii rămași pe lista din nou, debifați PQueue și continuați cu următoarea atribuire.

caveats:

  • Trebuie să fii atent că există întotdeauna destui oameni pentru o pozitie.
Publicat 02/01/2010 la 16:10
sursa de către utilizator

voturi
0

Ceea ce am înțeles este că sunt membri ai „m“ și „n“ poziții.

Categorie: un grup de posturi - un membru care i se atribuie o poziție în categoria nu poate avea o alta?

Grupa: un grup de poziții - poziții în același grup trebuie să fie alocate în zile diferite.

Ultimul lucru, o poziție are o listă de membri, care poate umple.

Privind la acest dintr-un punct de date de vedere al structurii, a pus membrii într-o listă legată - fiecare membru trebuie să aibă o listă suplimentară de [poziție, zi] că acestea sunt în cele din urmă alocate. Apoi, pentru fiecare poziție, au o listă de referințe la membrii care pot umple această poziție. Punerea în aplicare a categoriilor ca o altă listă de referințe pentru o poziție cu privire la ce categorii este în.

Actuala atribuire: au un contor zi = 0, și itera pozițiile. Pentru fiecare poziție P, itera prin membrii care îl pot umple. Un membru M poate umple poziția în cazul în care:

  • Orice poziție pe care a umplut P2 nu împarte o categorie cu P.
  • Orice poziție pe care a umplut P2 cu zi = daycounter nu împarte un grup cu P.

Dacă el poate umple poziție, [poziția, zi] se adaugă perechea de a membrului, iar nodul membrului este mutat la sfârșitul listei (acesta este motivul pentru care sunt necesare referințe - toate referințele sunt încă valabile, chiar dacă nod mutat). Acest lucru asigură că „SKIPPED“ membri sunt date cea mai mare prioritate, iar membrii care nu au fost atinse s-au dat următoarea cea mai mare prioritate.

Odată ce o poziție este umplut, du-te la poziția următoare. În cazul în care poziția împarte un grup cu o poziție deja atribuită, săriți peste ea, iterarea prin toate pozițiile, până când se pot asocia cât mai multe poziții, după cum puteți în ziua 1. Apoi, incrementa contorul de zi și se repetă pentru ziua 2. Acest lucru ar trebui să vă dea o misiune maximă (nu sunt sigur cu privire la maxim) pentru toate locurile de muncă.

Sfat: atunci când se deplasează un membru la sfârșitul listei de membri, pentru a preveni a trebui să traverseze lista, să păstreze o referință la sfârșitul anului - pentru poziția următoare, trebuie să pornească de la început, oricum, deci nu există nici un punct care trece prin toată chestia.

Publicat 02/01/2010 la 18:16
sursa de către utilizator

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