Search code examples
pythonmosek

Variables with indexes and sums with indexes in mosek


I have to find solutions to an integer programming problem:

enter image description here

I am using Mosek's Fusion API (Python). Now the constrains are easy to put in, I am more worried about the actual objective. The problem for me is: How can I tell mosek that I want to sum by all is, js or ks and define what they are, what are their boundaries, etc.?

This is a simplified version of a self-caching problem in the context of servers. So i here means a server, j means an object to cache, but in this version there's one object, so this I guess is not important. k means server too, so e.g. d(ik) means the distance from the server i to the server k.

But whatever I want to achieve, I don't know how to write this objective. For now I have something like this:

from mosek.fusion import Domain, Model, Expr, ObjectiveSense

alpha = 4 # alpha is the same for all i and j
demand = 1 # w is the same for all i and k
n = 6 # number of servers
distances_matrix = [[...], [...], ...]


with Model("lo1") as M:

    x = M.variable("x", n, Domain.integral(Domain.inRange(0, 1)))
    y = M.variable("y", n, Domain.integral(Domain.inRange(0, 1)))

    alpha_times_x = Expr.mul(alpha, x)
    demand_times_dist_times_y = Expr.mul(demand, distances_matrix, y)

    M.objective("obj", ObjectiveSense.Minimize, )

    M.solve()

    print(x.level())
    print(y.level())

Now of course the demand_times_dist_times_y is wrong, because I want to get the distance from i to k from the matrix. And the x above is fine since xs are: {x0, x1, x2, x3, x4, x5, x6}, but the ys would have to be {y11, y12, y13, y14, y15, y16, y21, y22, ..., y66}, so I guess I defined them wrong.

So e.g. how can I define that i,k are in {1,2,3,4,5,6} and create an Expr.sum by e.g. k? And how would I define those two sums at the beginning of the objective?


Solution

  • I don't know if that answers the question, but if you have, say

    x = M.variable("x", n, Domain.integral(Domain.inRange(0, 1)))
    

    then sum_i x_i is obtained with

    Expr.sum(x)
    

    Similarly, if now alpha is a numerical array of length n then sum_i (alpha_i*x_i) is obtained with

    Expr.sum( Expr.mulElm(alpha,x) )
    

    or even

    Expr.dot( alpha, x )
    

    and so on. You never explicitly specify the summation index, you are summing all entries of whatever appears inside the Expr.sum and similar methods.