Skip to main content

Mean-Variance-Shannon's Entropy

Answered

Comments

17 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    Yes, you can solve this problem with Gurobi. For the logarithm, you would have to use the addGenConstrLog() function.

    The bilinear terms can be modeled either through adding each constraint one by one or using the matrix API. We recommend having a look at our Matrix API webinar and our Python Example Tour. Additionally, our Knowledge Base article How do I model multilinear terms in Gurobi? may be helpful.

    Best regards,
    Jaromił

    0
  • Mark Stone
    Gurobi-versary
    First Comment

    Are you sure about that?  How is ln x handled?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Mark,

    Gurobi uses piecewise approximation for \(ln(x)\) and a couple of other functions. You can read more in the documentation on addGenConstrXxx().

    Best regards,
    Jaromił

    1
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    Thank you for your help.

    My main problem is the quadratic constraint of variance. I really don't know how to write it. I don't know if you can also solve it with MATLAB

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    It is possible in MATLAB as well. Please have a look at the MATLAB API Documentation and the MATLAB example tour. The logarithm can be modeled using so-called Function constraints.

    In order to slowly make progress in modeling, you can use the gurobi_write() function to write an LP file and inspect it to see whether the model you construct is actually correct.

    Best regards,
    Jaromił

    0
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    I found on the documentation you suggested that I can solve the problem using "qcp", but being unfamiliar with the software I don't know how to build the matrices on the gurobi interface for MATLAB.

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    Did you have a look at our MATLAB examples? In particular the examples bilinear.m, qp.m, and qcp.m should be helpful. You can find these examples in your Gurobi installation folder at \(\texttt{<pathToGurobi>/examples/matlab/}\).

    Best regards,
    Jaromił

    0
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    I have read the documentation but do not understand how to set the problem. My quadconstraints is represented by X^T*Sigma*X, where X is a ones(n,1) vector and sigma is a square matrix nxn. How can I write this constraint?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    Let's assume that your \(x^T \Sigma x\) provide the constraints

    \[\begin{align*}
    2x^2 - &xy  &= 0\\
    &xy +2y^2 &= 0
    \end{align*}\]

    You can model the above constraint by setting the values of each entry of the \(Q\) matrix as

    %Entry Qrow=1 and Qcol=1 is x^2
    %Entry Qrow=1 and Qcol=2 is xy
    %Entry Qrow=2 and Qcol=2 is y^2
    m.quadcon(1).Qrow=[1, 1];
    m.quadcon(1).Qcol=[1, 2];
    m.quadcon(1).Qval=[2, -1]; % value of coefficient for (Qrow=1,Qcol=1) is 2, value of coefficient for (Qrow=1,Qcol=2) is -1
    m.quadcon(1).q = sparse(2,1); % no linear terms so just create a sparse matrix filled with zeros
    m.quadcon(1).rhs =0;
    m.quadcon(1).sense='=';
    m.quadcon(1).name='c1';

    m.quadcon(2).Qrow=[1, 2];
    m.quadcon(2).Qcol=[2, 2];
    m.quadcon(2).Qval=[1, 2]; % value of coefficient for (Qrow=1,Qcol=2) is 1, value of coefficient for (Qrow=2,Qcol=2) is 2
    m.quadcon(2).q = sparse(2,1); % no linear terms so just create a sparse matrix filled with zeros
    m.quadcon(2).rhs =0;
    m.quadcon(2).sense='=';
    m.quadcon(2).name='c2';

    This basically means that you can define your constraints defined by \(x^T \Sigma x\) in a \(\texttt{for}\)-loop setting each constraint one by one in the loop.

    Best regards,
    Jaromił

    0
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    I tried to write the model this way, but gurobi couldn't solve it

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    What exactly do you mean by "Gurobi couldn't solve it"? Do you mean that the optimization does not converge or that some other error occured? Could you post the LOG file and/or the error code?

    Best regards,
    Jaromił

    0
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    Error using gurobi
    Incorrect size(model.obj)

    Error in Nicola (line 22)
    result=gurobi(model);

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    In order to use the logarithm, you have to make use of the \(\texttt{genconlog}\) function described in the documentation of the model argument. This means that you have to add an auxiliary variable \(w_i\) for each \(w_i=ln(x_i)\). Then, your objective function reads \(\mathbf{x}^T \cdot \mathbf{w}\). The matrix \(\texttt{Q}\) of the model object describes the quadratic part of the objective, i.e., this is the one you would have to properly set.

    Let's say you have 2 variables \(x_1,x_2\) and introduced 2 auxiliary variables \(w_1,w_2\), then your \(\texttt{Q}\) should be given as

    model.Q = sparse([0 0 0.5 0.5; 0 0 0.5 0.5; 0.5 0.5 0 0; 0.5 0.5 0 0])

    In general, we would recommend to switch to the Python API if possible, as modelling with the Python API is quite more intuitive compared to the MATLAB object based API.

    Best regards,
    Jaromił

     

    0
  • Andrea Muzi
    Gurobi-versary
    Conversationalist
    First Question

    But if \x_i is not defined ? \x_i is my objective variable. So, How can I write \w_i as a function of something that I don't have ?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Andrea,

    You would have to work with the matrices as if the auxiliary variables are there and then you have to set the \(\texttt{xvar}\) and \(\texttt{yvar}\) attributes of the \(\texttt{genconlog}\) object.

    I would strongly recommend to switch to the Python API as implementing your model with the use of Gurobi's Python API would be way easier and more intuitive.

    Best regards,
    Jaromił

    0
  • Macarena Navarro
    Gurobi-versary
    First Comment

    Hi Jaromil, I have the same question as Andrea, could you please give an example?

    Best regards, 

    Macarena

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Macarena,

    Please note that you can find example files for the usage of general constraints, bilinear terms, and Python Matrix API in our documentation.

    Nevertheless, here is a small example with 3 dimensional variables.

    import gurobipy as gp
    from gurobipy import GRB

    m = gp.Model("test")

    # create variables
    N = 3
    x = m.addVars(N,vtype=GRB.CONTINUOUS,name="x")
    mu = m.addVars(N,vtype=GRB.CONTINUOUS,name="mu")
    u = m.addVars(N,vtype=GRB.CONTINUOUS,name="u")
    lnx = m.addVars(N,vtype=GRB.CONTINUOUS,name="lnx")

    # constants
    eta = 1.1
    Sigma = [[1,2,3],[4,5,6],[7,8,9]]
    sigma0 = 1.2

    # add auxiliary equality constraint lnx_i = ln(x_i)
    for i in range(N):
    m.addGenConstrLog(x[i],lnx[i],name="lnx_constr_%d" % i)

    # set objective to sum x_i * lnx_i
    m.setObjective(gp.quicksum(x[i]*lnx[i] for i in range(N)), GRB.MINIMIZE)

    # add constraint mu^T * x = eta
    m.addConstr(gp.quicksum(mu[i]*x[i] for i in range(N)) == eta, name="mu_x_eta")

    # add constraing x^T * Sigma * x = sigma_0
    m.addConstr(gp.quicksum(x[i]*Sigma[i][j]*x[j] for i in range(N) for j in range(N)) == sigma0, name="x_Sigma_x_sigma0")

    # add constraint u^T * x = 1
    m.addConstr(gp.quicksum(u[i]*x[i] for i in range(N)) == 1, name="u_x_1")

    # write an LP file to analyze if the constructed problem is correct
    m.write("myLP.lp")

    Note that the above problem is infeasible because I used just some random values for the constants.

    Best regards,
    Jaromił

    0

Please sign in to leave a comment.