pythoncplexdocplex

Maximize the amount of zeros in continuous matrix (Python, docplex)


I have an optimization problem with a continuous matrix variable (C), but:

My objective function is not about min/max the entries of C, but to maximize the amounts of 0 in C. My approach to model this, is to translate C to heaviside(C), which would make all non-zero entries equal to 1 and all zero entries stay 0. Then i could minimize the sum of these matrix entries, resulting a maximum of zero entries.

model.set_objective('min', sum(np.heaviside(C[k,j], 0) for k, j in itertools.product(range(M), range(P))))

Here I get errors of cplex, because C does not have defined values at this point. Any kind of casting the values of C to int or float fails as well.

TypeError: ufunc 'heaviside' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

I do not understand, why this is a problem, while e.g.

model.set_objective('min', sum(C[k,j] for k, j in itertools.product(range(M), range(P))))

works fine.


Solution

  • numpy functions are not allowed you should turn them into functions that are in docplex.

    For instance you could rely on logical constraints

    from docplex.mp.model import Model
    
    mdl = Model(name='buses')
    nbbus40 = mdl.integer_var(name='nbBus40')
    nbbus30 = mdl.integer_var(name='nbBus30')
    mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
    mdl.minimize(nbbus40*460 + nbbus30*360)
    
    mdl.solve()
    
    for v in mdl.iter_integer_vars():
        print(v," = ",v.solution_value)
    
    print()
    print("with the logical constraint")
    
    nbKindOfBuses = mdl.integer_var(name='nbKindOfBuses')
    mdl.add(nbKindOfBuses==(nbbus40>=1)+(nbbus30>=1))
    
    mdl.minimize(nbbus40*460 + nbbus30*360+(nbKindOfBuses-1)*(500))
    
    mdl.solve()
    
    for v in mdl.iter_integer_vars():
        print(v," = ",v.solution_value)