IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

attributions de places


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2012
    Messages : 24
    Par défaut attributions de places
    Bonjour/bonsoir,

    je suis en train de travailler sur un projet d'attribution de places (chacun entre pour quels jours de la semaine il voudrait une place, puis les places disponibles sont distribuées par ordre de priorité).

    J'ai pour ainsi dire terminé la mise en place de l'entrée de toute les informations (dont places souhaitées et celles servant à calculer la priorité) et la mise en place d'une liste doublement chaînée des personnes classée par ordre de priorité.

    en soit, la distribution n'est pas très compliqué :
    je prend le premier de ma liste, je lui attribue les places qu'il demande
    je prend le second et je lui attribue parmi ce qu'il demande ce qu'il reste
    je continue de même pour le 3ème, le 4ème,... jusqu'à ce qu'il ne reste plus rien ou qu'il n'y ait plus personne qui veille de places

    le problème est que je souhaiterais ajouter une option permettant qu'on veut au maximum n places parmi celles demandées (par exemple on coche tous les jours et on indique un maximum de 2 si on souhaite avoir 2 jours sans que cela nous importe lesquels).
    Et là, je n'ai aucune idée comment procéder de manière à ce que chacun reçoit le mieux qu'on peut lui attribuer d'après sa priorité, en tenant compte que certaines personnes sont "flexibles" : je suppose qu'il faut les stocker dans une liste supplémentaire pour pouvoir modifier leur places au fur et à mesure, mais je ne sais pas comment faire pour être sur d’attribuer le mieux qui puisse être disponible au suivant quand il ne reste plus de places pour certains jours et qu'il faut les "libérer" en jouant sur les gens flexibles.

    par exemple :
    - la personne 1 demande 2 places parmi lundi, mardi et mercredi
    - la personne 2 demande 2 places parmi lundi, mardi et jeudi
    - la personne 3 demande toute la semaine

    il y a 2 places chaque jour

    il faut donc que la personne 1 reçoive le mercredi et lundi ou mardi, la personne 2 reçoit jeudi et lundi ou mardi (celui que la personne 1 à laissée), comme ça la personne 3 est elle aussi satisfaite.


    Ma question est donc comment organiser une telle distribution "intelligente"?
    à savoir que le programme n'est pas sensé être utilisé pour plus d'une centaine de personnes (75 environ) et que parmi celles-ci, la plupart n'utiliseront probablement pas cette option.

    Quelqu'un aurait-il donc une idée comment faire pour que s'il n'y a plus de places disponibles pour un/des jours, le programme réarrange si possible les personnes flexibles pour en libérer?

    Merci d'avance
    Katorps

    PS : si vous avez des questions et/ou pensez que d'autres informations seraient utiles, surtout n'hésitez pas à demander

  2. #2
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 82
    Par défaut
    Citation Envoyé par katorps Voir le message
    chacun entre pour quels jours de la semaine il voudrait une place, puis les places disponibles sont distribuées par ordre de priorité.
    - Comment tu définis les ordres de priorité?

    Après si j'ai compris ton problème j'ai une petite idée.

    En gros dès que tu as fini de placer une personne, tu regardes si cette personne a d'autres dispos qui ne sont pas contraignantes.
    Si c'est le cas tu stockes dans une liste chaînée, les jours ou cette personne n'a pas été attribué (ou il peut être placé) puis tu stockes les jours qu'on lui a attribué (ces jours ne doivent pas être "souhaité" par la personne).
    Donc cette liste chaînée possèdera des personnes que l'on peut déplacer sur d'autres jours sans lui modifier des jours qu'il a souhaité. (Dans cette liste tu ne peux pas avoir des personnes qui ne sont pas déplaçables).

    Ensuite quand tu attribues des jours à une personne, à chaque fois tu prends en compte les jour qui ont été coché "souhaité" et tu lui attribues. Si cette personne n'a pas de jour "souhaité" disponible tu regardes dans la liste chaînée s'il y a une personne qui est sur le jour souhaité. Si c'est le cas tu regardes si la personne peut être déplacé sur un autre jour (ou même changer avec une autre personne présente dans la liste). Si c'est le cas tu fais tes modifications dans tes 2 listes chaînées et tu passes à la personne suivante.

  3. #3
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    C’est plus une question d’algorithmique générale, ça… En fait, on rentre dans le vaste (et complexe) domaine de l’optimisation.

    Pour ce cas spécifique, on pourrait faire comme ça*:

    * Lorsqu’on rencontre un “flexible”, on lui attribue toujours les jours où il reste le plus de place, et on l’ajoute à une deuxième liste chaînée.
    * Lorsqu’on arrive à une situation non-satisfaisante (c-à-d une personne pour laquelle on ne peut satisfaire toutes ses demandes), on “note” les jours demandés, et on remonte la liste des flexibles, en regardant à chaque fois si on peut ajuster le flexible en court afin d’améliorer la situation.

    Par exemple, avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    P1(2) [lun, mar, mer]
    P2(2) [lun, mar, jeu]
    P3(5) [lun, mar, mer, jeu, ven]
    dispos: [lun:2, mar:2, mer:2, jeu:2, ven:2]
    …on a le déroulement suivant*:

    * P1: on attribue lundi et mardi.
    * P2: on attribue lundi et jeudi (où il reste plus de places que pour mardi!).
    * P3: on attribue mardi, mercredi, jeudi et vendredi. Il nous reste lundi à essayer de caser. On remonte sur P2, mais déplacer lundi sur mardi est impossible (il ne reste plus de place). On remonte sur P1, où on peut déplacer lundi sur mercredi.

    Et on obtient la solution optimale…

    Note*: a priori, je pense que, avec ces contraintes relativement simples, cet algo permet d’obtenir une situation optimale dans tous les cas (quitte peut-être à boucler plusieurs fois dans la liste des “flexibles” si nécessaire), mais ça reste à tester*!

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2012
    Messages : 24
    Par défaut
    Merci beaucoup pour vos réponses.

    Pour la question du calcul de priorité, je n'ai pas encore l'information exacte, mais c'est à base de critères tels que l'âge, les revenus, la situation familiale,... qui permettent d'obtenir un indice de priorité.

    Par contre dans les 2 cas, je vois encore un problème : quand une (ou plusieurs) place(s) sont demandées mais non disponibles directement, comment faire quand il faut faire plusieurs déplacements pour aboutir au résultat ?

    par exemple:
    P1(2) [lun,mar,mer]
    P2(2) [mar,mer,jeu]
    P3(1) [lun]
    dispo [lun:1 , mar:2, mer:1, jeu:1]

    on attribue à P1 : [lun,mar]
    à P2 : [mar,mer]

    pour P3, il faut un lundi : il faut dont pour cela un mercredi pour changer chez P1 : il faut donc échanger chez P3 le mercredi avec le jeudi.

    Comment faire pour trouver de telles "astuces" à l'aide du programme, surtout si c'est des cas un peu plus complexes (on peut avoir jusqu'à 5 déplacements à faire) tout en évitant les risques de tourner en boucles infinies?

    Merci d'avance
    katorps

    PS : si ça peut aider à mieux comprendre le problème, il s'agit de places de cantine (dans l'état actuel des choses, 26 places par jour pour 75 demandes): l'idée est donc de permettre aux parents qui par exemple peuvent choisir quel jour de la semaine ils ne travaillent pas de rester flexible pour augmenter leur chance d'avoir 4 repas sur la semaine)

  5. #5
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Oui, en effet, il y a des situations où l’algo proposé ne trouvera pas la solution optimale… En voici un autre, récursif. Mais encore une fois, il est probablement loin d’être optimal (et probablement peu adapté au-delà de quelque centaines de personnes maximum), je ne suis pas un spécialiste des algos d’optimisation…

    L’idée est, lorsqu’on arrive à un point de blocage, de relancer l’algo (donc récursivité) sur le sous-ensemble “personnes flexibles déjà traitées”, et avec un nouveau “nombre de places dispo” dont on a soustrait celles attribuées aux “personnes fixes”, élément “bloquant” inclus. Un exemple sera probablement la meilleur façon de l’expliquer*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    P1(2) [lun,mar,mer]
    P2(1) [jeu]
    P3(2) [mar,mer,jeu]
    P4(1) [lun]
    dispo [lun:1 , mar:2, mer:1, jeu:2]
    dispo_flex [lun:1 , mar:2, mer:1, jeu:2]
     
    P1 -> [lun, mar]
    P2 -> [jeu]
    dispo_flex -> [lun:1 , mar:2, mer:1, jeu:1]
    P3 -> [mar, mer]
    P4 -> impossible!
    // On appelle alors récursivement sur P1 et P3 uniquement, avec dispo = dispo_flex (P4 compris)
    dispo = [lun:0 , mar:2, mer:1, jeu:1]
    P1 -> [mar, mer]
    P3 -> [mar, jeu]
    // On a maintenant un ordonnancement P1,P2,P3 qui autorise P4!
    Si la personne bloquante est une “flexible”, il faut faire l’appel récursif pour chacune de ses combinaisons, afin de voir si l’une d’entre elle fonctionne. Évidemment, l’appel récursif ne doit se faire que sur le sous-ensemble “flexibles en amont dans la liste, élément bloquant exclu”. De cette façon, on a la garantie d’éviter la récursion infinie (par contre, dans le pire des cas, et avec que des personnes flexibles, on doit pouvoir arriver à autant de récusions qu’il y a de personnes dans la liste, donc celle-ci est limitée à quelque milliers d’éléments grand maximum*!).

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2012
    Messages : 24
    Par défaut
    Merci beaucoup pour ta réponse.

    En utilisant toutes les pistes que vous m'avez proposé, j'ai crée un pseudo-code (j'ai pas encore essayé de l'implanter) qui je crois devrait permettre de trouver dans tous les cas une solution si elle existe et en un temps raisonnable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    I)	S’il ne reste plus aucune place, on arrête 
    II)	On trie les jours : d’abord ceux en exigé puis les autres. On sous-tri par 
            nombre de places restantes
    III)	On teste s’il y a flexibilité. Si oui on ajoute à la liste des flexibles
    IV)	Tant que l’on n’a pas passé en revus les 5 jours ou atteint le maximum 
             souhaité ou qu’il ne reste plus aucune place
       1)	on regarde si le jour est disponible
          i)	si oui, on accorde (et réduit le nombre restant)
          ii)sinon
             a)s’il n’y a pas de flexibles ou si la disponibilité par flexibilité de ce jour
                est nulle : on passe au jour suivant
             b)s’il y a des flexibles : 
                •on crée L1= {J1}
                •on appelle la fonction récursive QUE_DEPLACER_POUR_LIBERER_UN_JOUR_UTILE (1)
                •si retour=SUCCES, on accorde, sinon, on passe au jour suivant
     
     
     
     
    Fonction QUE_DEPLACER_POUR_LIBERER_UN_JOUR_UTILE (K) :
    I)	 On crée une liste LK+1
    II)	Pour tous les éléments JK de LK
       1)	On parcourt la liste des flexibilités
          a)	Si on trouve un flexible permettant de libérer un JK, déplace ce 
                    flexible de JK au jour flexible (où on diminue de 1 le nombre de 
                    places) et on ajoute une place au jour JK .On termine l’appel de 
                    fonction en retournant SUCCES
       2)	On re-parcourt la liste des flexibles
          a)	on met dans LK+1 la liste des JK+1 qui s’ils étaient disponibles 
                    permettraient de libérer le JK en cours de traitement en excluant 
                    ceux appartenant à une LJ avec 1<=J<=K+1 et ceux dont la 
                    disponibilité par flexibilité est nulle
    III)	Si LK+1 est vide :
       1)	Si aucune place n’a été pour l’instant accordée à l’enfant, on met la 
            disponibilité par flexibilité de chaque élément des LJ avec 1<=J<=K à 0
       2)	Dans tous les cas, on termine l’appel de fonction en renvoyant ECHEC 
    IV)	Sinon (si LK+1 n’est pas vide) on appelle 
             QUE_DEPLACER_POUR_LIBERER_UN_JOUR_UTILE (K+1) :
       1)	si retour=SUCCES : on recommence au II)
       2)	si retour=ECHEC : on termine l’appel de fonction en renvoyant 
             ECHEC
    Vous semble-t-il que ça a une chance de fonctionner où ai-je laissé des failles?

    Merci d'avance
    Katorps

  7. #7
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Je ne suis pas sûr de comprendre complètement QUE_DEPLACER_POUR_LIBERER_UN_JOUR_UTILE… L’algo m’a l’air plus complexe que celui auquel j’avais pensé, mais c’est vrai que ça devient vite difficile d’être clair.

    L’un dans l’autre, je dirais que tu peux tenter le code, de toute façon, on n’est jamais sûr que ça marche avant d’avoir testé*!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Place des attributs
    Par jedebute_et... dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 19/03/2012, 11h17
  2. Attribution sur une place à un moment donné
    Par lylandra6 dans le forum Débuter avec Java
    Réponses: 0
    Dernier message: 02/06/2010, 00h25
  3. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39
  4. Lire un attribut dans un fichier XML en C++
    Par ti.k-nar dans le forum XML
    Réponses: 2
    Dernier message: 14/10/2002, 15h22
  5. comment changer d'attribut de fonte dans un Tlabel?
    Par sb dans le forum Composants VCL
    Réponses: 3
    Dernier message: 21/08/2002, 16h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo