-1

I'm trying to solve optimaztion problem of assigning doctor to surgry and for room when the main goal is to minimize the number of docotors. I have start and end time, number of surgeries and number of rooms. I try to use OR-TOOLS to solve the problem with diffrent constaints but i get empty solution. How can i know where is the problem and print the constraint to understand if there is problem in their defintion?

The code is:

def getTimediffrence(start,end):
    startTime = datetime.datetime.strptime(start, '%m/%d/%Y %H:%M')
    endTime = datetime.datetime.strptime(end, '%m/%d/%Y %H:%M')
    timeDiff =  startTime - endTime
    return int(timeDiff.total_seconds() / 60)


surgery_times = {0: ('4/25/2023 7:00', '4/25/2023 7:15'), 1: ('4/25/2023 7:00', '4/25/2023 7:30'), 2: ('4/25/2023 7:00', '4/25/2023 7:30'), 3: ('4/25/2023 7:00', '4/25/2023 7:30'), 4: ('4/25/2023 7:00', '4/25/2023 7:45'), 5: ('4/25/2023 7:00', '4/25/2023 8:00'), 6: ('4/25/2023 7:00', '4/25/2023 8:45'), 7: ('4/25/2023 7:00', '4/25/2023 9:45'), 8: ('4/25/2023 7:15', '4/25/2023 7:30'), 9: ('4/25/2023 7:15', '4/25/2023 7:30'), 10: ('4/25/2023 8:00', '4/25/2023 8:15'), 11: ('4/25/2023 8:00', '4/25/2023 8:45'), 12: ('4/25/2023 8:00', '4/25/2023 9:00'), 13: ('4/25/2023 9:15', '4/25/2023 10:30'), 14: ('4/25/2023 9:30', '4/25/2023 10:30'), 15: ('4/25/2023 9:30', '4/25/2023 10:45'), 16: ('4/25/2023 9:45', '4/25/2023 10:30')}


def solve_surgery_assignment(analysis_dict):
    model = cp_model.CpModel()
    
    #Decision varaibles
    num_doctors = len(analysis_dict)
    num_rooms = 5
    num_analyses = len(analysis_dict)

    # Create a variable to represent the assignment of doctors to surgeries
    # Variable x[i, j, k] is 1 if doctor i is assigned to surgery j in room k
    x = {}
    for i in range(num_doctors):
        for j in range(num_analyses):
            for k in range(num_rooms):
                x[(i, j, k)] = model.NewBoolVar(f'x[{i},{j},{k}]')

    # Constraint 1: Each surgery must be assigned to a doctor
    for j in range(num_analyses):
        model.Add(sum(x[(i, j, k)] for i in range(num_doctors) for k in range(num_rooms)) == 1)

    # Constraint 2: Each doctor must be in only one surgery at the same time
    for i in range(num_doctors):
        for k in range(num_rooms):
            model.Add(sum(x[(i, j, k)] for j in range(num_analyses)) <= 1)

    # Constraint 3: Doctor must remain during the entire surgery
    for i in range(num_doctors):
        for j in range(num_analyses):
            for k in range(num_rooms):
                model.Add(sum(x[(i, jj, k)] for jj in range(j, num_analyses)) >= x[(i, j, k)])

    # Constraint 4: Each room has one surgery at a given time
    for j in range(num_analyses):
        for k in range(num_rooms):
            model.Add(sum(x[(i, j, k)] for i in range(num_doctors)) <= 1)

    # Constraint 5: A doctor moves to a different room if there is a gap of at least 15 minutes
    # Assuming analysis_dict contains the start and end times for each surgery
    for j in range(num_analyses - 1):
        for i in range(num_doctors):
            for k in range(num_rooms):
                for l in range(k + 1, num_rooms):
                    difftime = getTimediffrence(analysis_dict[j+1][0],analysis_dict[j][1])
                    model.Add(sum(x[(i, jj, l)] for jj in range(j + 1, num_analyses)) <=
                              (sum(x[(i, jj, k)] for jj in range(j, num_analyses)) +
                               (difftime) // 15))

    # Objective function: Minimize the number of doctors needed
    objective = sum(x[(i, j, k)] for i in range(num_doctors)
                    for j in range(num_analyses) for k in range(num_rooms))
    model.Minimize(objective)

    # Solve the model
    solver = cp_model.CpSolver()

    # Sets a time limit of 10 seconds.
    # solver.parameters.max_time_in_seconds = 60.0

    status = solver.Solve(model)

    solution = {}
    # Get the optimal solution
    if status == cp_model.OPTIMAL:
        for i in range(num_doctors):
            for j in range(num_analyses):
                for k in range(num_rooms):
                    if solver.Value(x[(i, j, k)]) == 1:
                        solution[(j, k)]=i

    doctor_list = []
    start_time_list = []
    end_time_list = []
    room_list = []

    for surgery, doctor in solution.items():
        surgery_index, room_index = surgery
        start_time, end_time = analysis_dict[surgery_index]

        # Append the information to the respective lists
        doctor_list.append(doctor)
        start_time_list.append(start_time)
        end_time_list.append(end_time)
        room_list.append(room_index + 1)  # Assuming 1-based room index

        print(f"Room {room_index + 1}:")
        print(f"Surgery {surgery_index + 1} - Doctor {doctor}")
        print(f"Start Time: {start_time} minutes")
        print(f"End Time: {end_time} minutes")
        print()

    # Create the DataFrame
    df = pd.DataFrame({
        'start_time': start_time_list,
        'end_time': end_time_list,
        'anesthetist_id': doctor_list,
        'room_id': room_list
    })


    df.to_csv('schduled.csv')


solve_surgery_assignment( surgery_times)

1 Answers1

0

The first thing to do is to enable logging: solver.parameters.log_search_progress = True

Your problem is trivially infeasible.

Here is the log:

Initial optimization model '': (model_fingerprint: 0xd5fc7ae7132b762b)
#Variables: 1445 (#bools:1445 in objective)
  - 1445 Booleans in [0,1]
#kLinear1: 85
#kLinear2: 85
#kLinear3: 255
#kLinearN: 3927 (#terms: 65280)

Starting presolve at 0.01s
INFEASIBLE: ''

Presolve summary:
  - 0 affine relations were detected.
Problem closed by presolve.

Digging around, your model is very suspicious Nowhere in the data x you speak about time.

Still, each doctor can only do 1 surgery (ct 2). Ct3 makes no sense to me, but ok.

and ct5 is most likely wrong.

Laurent Perron
  • 8,594
  • 1
  • 8
  • 22