problème de planification d'emploi

voix
8

Je travaille sur une application où je dois planifier automatiquement des emplois pour les membres sur un calendrier de rotation. Je ne suis pas très bon à expliquer les règles, voici donc quelques données pour aider:

Positions: Un titre du poste, avec des règles telles que les lundis et mercredis par semaine.
Catégories: un ensemble de positions
groupes: Une autre série de positions. Positions dans le même groupe ne peuvent pas être attribués le même jour
Membres: Les utilisateurs affectés à des postes à une date donnée.

Pour chaque date dans le mois, les membres sont affectés à des postes (à la fois dans l'ordre croissant). Si un membre est affecté à un poste dans une catégorie, la prochaine fois une position dans la même catégorie arrive, le membre suivant par ordre alphabétique (ou le début de la liste) est attribué, par exemple.

Membres: M1, M2, M3, M4
positions dans la catégorie C1: P1, P2, P3
Membres en position P1: M1, M2, M3, M4
Membres en position P2: M1, M2, M3
Membres en position P2: M1, M3, M4

Si M1 est attribué pour P1, P2 si vient ensuite, M2 sera attribué. est introduit une couche supplémentaire de complexité où se P3 vient ensuite à la place, M3 se voit assigner. Le système doit garder une trace du fait que M2 a été « ignorée » et assigner M2 suivant le cas échéant, puis attribuez-lui M4 suivant, ou attendre jusqu'à ce qu'il atteigne une position où M2 est disponible (cela devient plus complexe quand il y a beaucoup de « sautée ' membres).

Un membre sera également ignorée s'il a indiqué qu'il ne sera pas disponible à cette date. Le système doit accorder la priorité aux membres sautées, les identifier en quelque sorte quand ils viennent, puis passer à la personne suivante logique dans la liste. Skipping applique également aux groupes en raison des affrontements de date.

J'ai déjà une solution temporaire [et désordre] que je ne comprends plus, même si j'ai beaucoup de commentaires dans ce expliquant chaque étape. Ses faiblesses sont à faire face aux membres sautées.

Si vous allez coder ce comment iriez-vous à ce sujet? Je la mise en œuvre en PHP, mais ce pseudocode travaillerais aussi bien.

Créé 19/12/2009 à 11:20
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
1

UFF. Je ne suis pas la description que vous, mais dans des situations similaires j'ai utilisé sql pour résoudre ce genre de problème. si vous utilisez php je suppose que vous avez sql disponible.

ce que je vous conseille de faire est de trouver un moyen de stocker ces informations dans un ensemble de tables et ensuite travailler sur ce requête SQL vous donne la réponse que vous voulez. bien souvent, il est beaucoup plus simple à faire dans sql que dans un langage procédural.

pour la partie sautée, par exemple, vous pourriez avoir une colonne qui enregistre quand quelqu'un a été attribué en dernier, puis par ordre que (de manière à sélectionner la personne qui n'a pas été affecté depuis longtemps). Sinon, vous pourriez avoir le nombre de fois sautées comme une colonne et l'ordre par là.

Créé 19/12/2009 à 13:09
source utilisateur

voix
6

Ma solution: Vous avez besoin d'un PriorityQueue (qui est disponible en PHP sous SplPriorityQueue). Le PriorityQueue vous donne des éléments de priorité décroissant (triées par des valeurs, la plus petite valeur la plus haute priorité).

Chaque membre reçoit une valeur attribuée. Cette valeur est un nombre ASCII avec n chiffres (vous pouvez utiliser 8 chiffres pour plus de commodité), remplis de zéros à n positions. Après cela, vous pouvez ajouter le nom. Vous ajoutez également à chaque membre des postes disponibles

Donc (n = 5):

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

Cela rend plus facile à trier les membres par priorité et le nom.

Préparation:

Une journée ensoleillée. Vous récupérez les positions assignées et une catégorie pour un jour donné. Chaque membre est chargé sur une longue liste. Chaque membre qui n'apparaît pas sur le travail n'est pas chargé, mais obtient sa valeur a diminué de moins deux. Bob n'est pas ici, donc sa nouvelle valeur se 99997Bob. Cela signifie que Bob sera sélectionné automatiquement la prochaine fois. Tous les autres membres obtiennent leur valeur a diminué d'un moins.

Les positions attribuées à un jour spécifique sont mis en correspondance (utilisation SplObjectStorage):

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

La carte ne contient que les positions qui doivent être attribués ce jour. Après le

Filtre: Vous devez rechercher les groupes et supprimer toutes les positions sur la carte qui ne peut être attribué ce jour. Votre description du groupe est un peu clair.

Attribuer:

  • Vous choisissez la position d'assigner
  • Obtenir la liste des membres qui peuvent occuper le poste
  • Supprimer des membres disponibles de la liste et de les mettre dans le PriorityQueue
  • Assigner la position par l'extrait () de PriorityQueue (affectation correcte est fait automaticially). Chaque membre qui est attribué volonté obtient sa valeur a augmenté d'un (Ainsi, les niveaux de diminution et d'augmenter si vous êtes ici et travailler). Si vous êtes ici et non affecté à un poste pour une raison quelconque, vous obtenez une petite pénalité d'un. Si vous pas ici, vous obtenez une pénalité de deux.
  • Après la fin, mettre les membres restants sur la liste à nouveau, désactivez la pqueue et poursuivre la mission suivante.

avertissements:

  • Vous devez faire attention qu'il ya toujours assez de gens pour une position.
Créé 02/01/2010 à 16:10
source utilisateur

voix
0

Ce que je comprends est qu'il ya des membres « m » et « n » des positions.

Catégorie: un groupe de postes - un membre qui est attribué une position dans la catégorie ne peut pas avoir une autre?

La groupe: un groupe de postes - postes au sein du même groupe doit être affecté à des jours différents.

La dernière chose, une position a une liste de membres qui peuvent le remplir.

En regardant cela d'un point de vue de la structure de données, mettre les membres dans une liste, - chaque membre doit avoir une liste supplémentaire de [poste, jour] qu'ils sont finalement affectés. Ensuite, pour chaque poste, une liste de références aux membres qui peuvent remplir cette position. Mettre en œuvre des catégories comme une autre liste de références pour une position à laquelle il est en catégories.

L'affectation réelle: un compteur a jour = 0, et itérer les positions. Pour chaque position P, itérer les membres qui peuvent le remplir. Un élément M peut remplir la position si:

  • Toute position qu'il a rempli P2 ne partage pas une catégorie avec P.
  • Tout poste qu'il a rempli P2 = jour daycounter ne partage pas un groupe avec P.

S'il peut remplir la position, la [position jour] paire est ajouté au membre, et le nœud du membre est déplacé à la fin de la liste (ce qui est la raison pour laquelle les références sont nécessaires - toutes les références sont toujours valables même si la noeud déplacé). Cela garantit que les membres de « sautée » sont la plus haute priorité, et les membres qui ne sont pas atteints ont reçu la priorité suivante.

Une fois qu'une position est remplie, allez à la position suivante. Si la position partage un groupe avec une position déjà attribué, sauter, itérer toutes les positions jusqu'à ce que vous pouvez affecter autant de positions que vous pouvez le jour 1. Ensuite, incrémenter le compteur de jour et répéter pour le jour 2. Cela devrait vous donner une affectation maximale (pas sûr maximum) pour tous les emplois.

Astuce: lors du déplacement d'un membre à la fin de la liste des membres, pour éviter d'avoir à parcourir la liste, conserver une référence à la fin - pour la position suivante, vous devez commencer dès le début de toute façon, donc il n'y a pas de point de passer par le tout.

Créé 02/01/2010 à 18:16
source utilisateur

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