Skip to main content

Minimize number of nonzero entries

Answered

Comments

6 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • Jaromił Najman
    • Gurobi Staff

    Hi Christoph,

    Since you are trying to compute a norm and only need access to specific rows of the matrix, it might be easier to use the standard Python API. A possible code would be

    import gurobipy as gp
    from gurobipy import GRB

    m = gp.Model("vector optimization")
    n_messwert = 6
    n_zustand = 4
    H = np.array([[1, 0, 3, 0],
    [2, 4, 0, 2],
    [0, 0, 1, 0],
    [5, 0, 2, 3],
    [2, 5, 2, 0],
    [2, 4, 0, 1]])

    alpha = m.addVar()
    c = m.addVars(n_zustand, name="c")
    a = m.addVars(n_messwert, name="a")

    m.addConstr( gp.quicksum(H[2][j]*c[j] for j in range(n_zustand) ) == 1)
    m.addConstr( gp.quicksum(H[2][j]*c[j] for j in range(n_zustand) ) == a[2])
    m.addConstr( gp.quicksum(a[i] for i in range(n_messwert)) ==
    gp.quicksum( gp.quicksum( H[i][j]*c[j] for j in range(n_zustand)) for i in range(n_messwert) ) )

    m.setObjective(gp.quicksum(a[i] for i in range(n_messwert)), GRB.MINIMIZE)
    m.write("myLP.lp")
    m.optimize()

    I used the write() function to write an LP file and check whether the created model looks as expected. Since you are interested in the \(l_0\), the easiest way would be to set all non-zero entries of your matrix \(H\) to 1 and use binary variables for your variables \(a\) and \(c\).

    Best regards,
    Jaromił

    0
  • Christoph Zöll
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił,

    The possible code using the Python API looks great. 

    variable a has to be a linear combination of H and I need it  for further use. So i can not switch up H.

    Can i weight the elements like:*

    m.setObjective(gp.quicksum(9999*a[i] for i in range(n_messwert)), GRB.MINIMIZE)

    Will the optimization try to get much zero entries since 9999*0=0 and non zero entries gets very big?

     

     

    0
  • Jaromił Najman
    • Gurobi Staff

    HI Christoph,

    A big M approach might work but can lead to nasty numerics and can be hard to debug. An alternative might be to add only \(\neq 0\) entries during constraint construction. A possible code would be

    m.addConstr( gp.quicksum( c[j] for j in range(n_zustand) if H[2][j]!=0 ) == 1)
    m.addConstr( gp.quicksum( c[j] for j in range(n_zustand) if H[2][j]!=0 ) == a[2])
    m.addConstr( gp.quicksum( a[i] for i in range(n_messwert)) ==
    gp.quicksum( gp.quicksum( c[j] for j in range(n_zustand) if H[i][j]!=0 ) for i in range(n_messwert) ) )

    This way, you still keep your matrix \(H\) and the entries of the matrix don't affect the constraints.

    Best regards,
    Jaromił

    0
  • Christoph Zöll
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił,

    try to implement your ideas in my project but i get an unsolveable/ unbounded problem.

    In my project matrix H is 142x55 and includes elements < 0 too.

    Even for a & c the lower bound is lb = -GRB.INFINITY so the can get values <0 too.

    Is it still usefull and possible get use of quicksum() under these conditions?

     

     

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Christoph,

    I don't understand how the negative coefficients affect the solution process, because in my suggestion they are not used except when checking whether they are \(\neq 0\). You could compute the unbounded ray to check which direction is unbounded  by making your problem continuous and setting the InfUnbdInfo parameter. You can access the unbounded ray via the UnbdRay attribute.

    Best regards,
    Jaromił

    0

Post is closed for comments.