web-dev-qa-db-fra.com

problème de satisfaction de contrainte manquant une contrainte

Je suis un professeur de pratiques de laboratoire à l'université, sur la base des commentaires des étudiants de l'année dernière, nous voulions, mon patron et moi, y répondre. Mon patron a choisi d'aller avec l'écriture d'un script C et je choisis python (python-constraint) pour essayer de résoudre notre problème.

Les informations

  • Il y a 6 séances
  • Il y a 4 rôles
  • Il y a 6 pratiques
  • Il y a 32 étudiants
  • Il y a 4 étudiants par équipe

Problème:

Attribuez à chaque élève 4 rôles, dans 4 pratiques en 4 sessions différentes.

Contraintes :

  1. Les étudiants devraient jouer un rôle une fois
  2. Les étudiants doivent faire 4 pratiques différentes sur 6
  3. Les étudiants ne doivent faire qu'une seule pratique par session
  4. L'élève ne devrait rencontrer le même compagnon qu'une seule fois

Modèles:

Voici le modèle que je ressens avec les étudiants, où chaque équipe est composée de 4 étudiants, les positions [0, 1, 2 ou 3] sont des rôles qui leur sont assignés. Chaque poste disponible est numéroté de 1 à 128

[# Semester
   [ # Session
     [ # Practice/Team
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, 42, 43, 44],
  [45, 46, 47, 48]],
 [[49, 50, 51, 52],
  [53, 54, 55, 56],
  [57, 58, 59, 60],
  [61, 62, 63, 64],
  [65, 66, 67, 68],
  [69, 70, 71, 72]],
 [[73, 74, 75, 76],
  [77, 78, 79, 80],
  [81, 82, 83, 84],
  [85, 86, 87, 88],
  [89, 90, 91, 92],
  [93, 94, 95, 96]],
 [[97, 98, 99, 100],
  [101, 102, 103, 104],
  [105, 106, 107, 108],
  [109, 110, 111, 112]],
 [[113, 114, 115, 116],
  [117, 118, 119, 120],
  [121, 122, 123, 124],
  [125, 126, 127, 128]]]

En d'autres termes :

Ceci est une session:

 [[1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12],
  [13, 14, 15, 16],
  [17, 18, 19, 20],
  [21, 22, 23, 24]],

Ces équipes font la même pratique:

[
    [1, 2, 3, 4],
    [25, 26, 27, 28],
    [49, 50, 51, 52],
    [73, 74, 75, 76],
    [97, 98, 99, 100],
    [113, 114, 115, 116]
]

Ces positions jouent le même rôle:

[
   1,
   5,
   9,
   13,
   17,
   21,
   25,
   ...
]

Ce que j'ai jusqu'à présent:

En utilisant python-constraint j'ai pu valider les trois premières contraintes:

Valid solution : False
            - sessions  : [True, True, True, True, True, True]
            - practices : [True, True, True, True, True, True]
            - roles     : [True, True, True, True]
            - teams     : [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False]

Pour ceux qui peuvent être intéressants, je fais simplement ceci:

Pour chaque condition, j'utilise AllDifferentConstraint . Par exemple, pour une session, je fais:

problem.addConstraint(AllDifferentConstraint(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])

Je ne suis pas en mesure de trouver un moyen de contraindre l'équipe, ma dernière tentative sur l'ensemble du semester était la suivante:

    def team_constraint(self, *semester):
        students = defaultdict(list)

        # get back each teams based on the format [# Semester [ #Session [# Practice/Team ... 
        teams = [list(semester[i:i+4]) for i in range(0, len(semester), 4)]

        # Update Students dict with all mate they work with
        for team in teams:
            for student in team:
                students[student] += [s for s in team if s != student]

        # Compute for each student if they meet someone more than once 
        dupli = []
        for student, mate in students.items():
            dupli.append(len(mate) - len(set(mate)))

        # Loosly constraint, if a student meet somone 0 or one time it's find
        if max(dupli) >= 2:
            print("Mate encounter more than one time", dupli, min(dupli) ,max(dupli))
            return False
        pprint(students)
        return True

Des questions :

  1. Est-il possible de faire ce que je veux pour les conditions de l'équipe? Ce que je veux dire, c'est que je n'ai aucune idée s'il est possible d'affecter 12 camarades à chaque élève et que chacun d'eux ne rencontre le même compagnon qu'une seule fois.
  2. Pour la contrainte d'équipe, ai-je manqué un algorithme plus performant?
  3. Des pistons que je peux suivre?
13
Florian Bernard

Juste une idée d'algorithme de permutation, pour chaque itération pourrait être concentrée sur un de chaque étudiant ou dans une de chaque session:

Session 1:
Roles
1,2,3,4
Students
1,2,3,4

(Note is 1st permutation 1234)

Sess 2 for student 1
Roles 1234
Students 5,1,7,6

Ici, l'étudiant 2 prend la place de l'étudiant 1 dans la session 1 et continue comme ceci

Roles 1234
St 2,5,6,7 

Continuer avec l'élève 1 S3 R 1234 St 10,9,1,8

S4
R 1234
St 11,12,13,1

À la fin, vous supprimez les interactions pour l'étudiant 1, comme sur les permutations pour la prochaine itération que vous supprimez en cours.

C'est comme un rubiks cube.

Si vous arrivez à coder ceci ou connaissez du code avec cet algo, faites le moi savoir.

Peut-être avec les itertools permutations

Les sessions étant> que des pratiques, je crois que ce n'est pas pertinent son nombre. Juste un peu de piscine pour prendre plus quand vous manquez ou plus de place pour la rotation. Peut-être pourrait simplifier le problème en visant 4 sessions = pratiques?

0
Cristo