Spaces:
Sleeping
Sleeping
File size: 5,445 Bytes
48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 48d920c 28d83d0 | 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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # -*- coding: utf-8 -*-
"""optimisation_examen_PMNE.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1Uewn7e8zZiGZdAAYHqXJtl-3TA7sj5eL
"""
#!pip install pulp
#!pip install gradio
import gradio as gr
import pandas as pd
from pulp import LpMinimize, LpProblem, LpVariable, lpSum
def planifier_examens(examens_text, salles_text, jours_text, creneaux_text, disponibilite_salle_text, conflits_text):
# --- 1. Parsing des données ---
# Examens
examens = []
for line in examens_text.strip().splitlines():
parts = line.split(',')
if len(parts) == 3:
exam_id, nb_students, duration = parts
examens.append((exam_id.strip(), int(nb_students.strip()), int(duration.strip())))
# Salles et capacités
salles = {}
for line in salles_text.strip().splitlines():
parts = line.split(',')
if len(parts) == 2:
room_id, capacity = parts
salles[room_id.strip()] = int(capacity.strip())
# Jours et créneaux
jours = [int(j.strip()) for j in jours_text.split(',')]
creneaux = [int(c.strip()) for c in creneaux_text.split(',')]
# Disponibilité des salles
disponibilite_salle = {}
for line in disponibilite_salle_text.strip().splitlines():
parts = line.split(',')
room_id = parts[0].strip()
disponibilite_salle[room_id] = [int(s) for s in parts[1:]]
# Conflits entre examens
conflits = []
for line in conflits_text.strip().splitlines():
parts = line.split(',')
conflits.append((parts[0].strip(), parts[1].strip()))
# --- 2. Modélisation avec PuLP (PMNE) ---
model = LpProblem("Planification_Examens", LpMinimize)
# Variables de décision
X = {(e, d, c, s): LpVariable(f"X_{e}_{d}_{c}_{s}", cat="Binary")
for e, _, _ in examens for d in jours for c in creneaux for s in salles}
Y = {d: LpVariable(f"Y_{d}", cat="Binary") for d in jours}
# Contrainte 1 : Chaque examen doit être programmé une seule fois
for e, _, _ in examens:
model += lpSum(X[e, d, c, s] for d in jours for c in creneaux for s in salles) == 1
# Contrainte 2 : Capacité des salles respectée
for d in jours:
for c in creneaux:
for s in salles:
model += lpSum(nb_students * X[e, d, c, s] for e, nb_students, _ in examens) <= salles[s]
# Contrainte 3 : Une salle ne peut accueillir qu’un seul examen par créneau
for d in jours:
for c in creneaux:
for s in salles:
model += lpSum(X[e, d, c, s] for e, _, _ in examens) <= 1
# Contrainte 4 : Disponibilité des salles
for e, _, _ in examens:
for d in jours:
for c in creneaux:
for s in salles:
if disponibilite_salle[s][c - 1] == 0:
model += X[e, d, c, s] == 0
# Contrainte 5 : Conflits entre examens (ne pas être en même temps)
for e1, e2 in conflits:
for d in jours:
for c in creneaux:
model += lpSum(X[e1, d, c, s] for s in salles) + lpSum(X[e2, d, c, s] for s in salles) <= 1
# Contrainte 6 : Activation des jours
for d in jours:
for e, _, _ in examens:
for c in creneaux:
for s in salles:
model += Y[d] >= X[e, d, c, s]
# Fonction Objectif : Minimiser le nombre de jours utilisés
model += lpSum(Y[d] for d in jours)
# --- 3. Résolution ---
model.solve()
# --- 4. Extraction des résultats ---
planning = []
for e, _, _ in examens:
for d in jours:
for c in creneaux:
for s in salles:
if X[e, d, c, s].varValue == 1:
planning.append({"Examen": e, "Jour": d, "Créneau": c, "Salle": s})
df = pd.DataFrame(planning)
df.to_csv("planning_examens.csv", index=False)
return df, "planning_examens.csv"
# Interface avec Gradio
with gr.Blocks() as demo:
gr.Markdown("# 📅 Planification des Examens avec PMNE et Gradio")
exams_input = gr.Textbox(label="Examens (exam_id, nb_étudiants, durée)", lines=5,
value="E1, 30, 2\nE2, 25, 1\nE3, 40, 2\nE4, 20, 1")
rooms_input = gr.Textbox(label="Salles (room_id, capacité)", lines=3,
value="S1, 50\nS2, 30\nS3, 40")
jours_input = gr.Textbox(label="Jours disponibles (séparés par des virgules)", value="1, 2, 3")
creneaux_input = gr.Textbox(label="Créneaux disponibles (séparés par des virgules)", value="1, 2, 3, 4")
disponibilite_input = gr.Textbox(label="Disponibilité des salles (room_id, slot1, slot2, ...)", lines=4,
value="S1, 1, 1, 1, 1\nS2, 1, 1, 0, 1\nS3, 1, 1, 1, 0")
conflits_input = gr.Textbox(label="Conflits entre examens (exam1, exam2)", lines=3,
value="E1, E3")
output_table = gr.Dataframe(headers=["Examen", "Jour", "Créneau", "Salle"], label="Planning des examens")
output_file = gr.File(label="Télécharger le planning")
solve_btn = gr.Button("Planifier les examens")
solve_btn.click(
fn=planifier_examens,
inputs=[exams_input, rooms_input, jours_input, creneaux_input, disponibilite_input, conflits_input],
outputs=[output_table, output_file]
)
demo.launch()
|