Speed up runtime MOSEK for cvxpy

I’m having issues with the following Python code:

# Import libraries
import pandas as pd
import numpy as np
import random
import cvxpy as cp
import matplotlib.pyplot as plt

K_c = {'low': [0, 1], 'general': [2, 3], 'high': [4, 5]}
K = np.arange(max(max(K_c.values()))+1)

situations = 10

t_start_list = []
t_end_list = []
P_list = []
J_list = []

for i in range(situations):
    t_start = {}
    t_end = {}
    P = {}
    J = np.zeros(len(K))

    for k in K:
        J[k] = random.randint(1, 2)
        rand_nums = sorted([random.uniform(0, 1) for _ in range(int(J[k]))])
        probabilities = [rand_nums[0]] + [rand_nums[i] - rand_nums[i - 1] for i in range(1, int(J[k]))] + [1 - rand_nums[-1]]
        intervals = sorted(np.random.choice(np.arange(14), int(J[k]), replace=False))   
        for j in range(int(J[k])):
            t_start[k, j] = intervals[j]
            P[k,j] = probabilities[j]
        for j in range(int(J[k])):    
            if j != int(J[k])-1:
                t_end[k, j] = random.randint(t_start[k, j], t_start[k, j+1]-1)
            elif j == int(J[k])-1:
                t_end[k, j] = random.randint(t_start[k, j], 13)
                
    t_start_list.append(t_start)
    t_end_list.append(t_end)
    P_list.append(P)
    J_list.append(J)

df = pd.DataFrame({
    't_start': t_start_list,
    't_end': t_end_list,
    'P': P_list,
    'J': J_list
})

# Define the sets
C = ['low', 'general', 'high']
S = ['early', 'late']
B = {'early': 2, 'late': 2}
T = {'early': [0, 1, 2, 3, 4, 5, 6], 'late': [7, 8, 9, 10, 11, 12, 13]}

objective_values = []

for i in range(situations):
    t_start = df['t_start'][i]
    t_end = df['t_end'][i]
    P = df['P'][i]
    J = df['J'][i]

    # Define the decision variables
    d_j = cp.Variable((len(K), int(J.sum())), nonpos=False, integer=True)
    d_t = cp.Variable((len(K), sum(len(T[s]) for s in S)), nonpos=False, integer=True)
    y = cp.Variable(sum(len(T[s]) for s in S), nonpos=False, integer=True)

    # Define the success functions
    f = {'low': (lambda d: cp.exp(-3 * d)), 'general': (lambda d: cp.exp(-2 * d)), 'high': (lambda d: cp.exp(-1 * d))}
    
    # Define the objective function
    objective = cp.Minimize(cp.sum([sum(P[k, j] * f[c](d_j[k, j]) for c in C for k in K_c[c] for j in range(int(J[k])))]))

    # Define the constraints
    constraints = []
    for k in K:
        for j in range(int(J[k])):
            for t in range(t_start[k, j], t_end[k, j]+1):
                constraints.append(d_j[k, j] == d_t[k, t])
    for s in S:
        for t in T[s]:
            constraints.append(cp.sum(d_t[:,t]) + y[t] == B[s])
        for t in T[s][1:]:
            constraints.append(y[t] == y[t-1] - cp.sum(d_t[:,t]-d_t[:,t-1]))
            constraints.append(cp.sum(cp.maximum(0, d_t[:,t]-d_t[:,t-1])) <= y[t-1])

    constraints.append(d_j >= 0)
    constraints.append(d_t >= 0)
    constraints.append(y >= 0)     

    # Define the problem
    problem = cp.Problem(objective, constraints)

    # Solve the problem
    problem.solve(solver = 'MOSEK', warm_start=True, verbose = True)
    
    # Save the objective value
    objective_values.append(problem.value)

plt.boxplot(objective_values)
 
# show plot
plt.show()

It takes very long to run. How can I speed up runtime?
Thanks in advance!

This is a forum for CVX in Matlab, and not CVXPY in Python.

A more suitable forum for your question will be:

https://groups.google.com/g/mosek

or you can write directly to Mosek support.

Having said that I ran your code and I think you stumbled over some accidental debug stuff. Please use Mosek version at most 10.1.13, there everything runs very nicely, and soon we will release a fix to the latest version.

Just for completeness, if someone is looking for information about what to do with a MIP that is slow for “natural” reasons, then I recommend

and

https://docs.mosek.com/latest/pythonapi/mip-optimizer.html

Hi Michal,

Thank you very much for your help. Using version 10.1.13 indeed works.

Best regards

Version 10.1.19 fixes this again.