def buildSolverModel(self, lp, inf=1e20):
     """Translate the problem into a Mosek task object."""
     self.cons = lp.constraints
     self.numcons = len(self.cons)
     self.cons_dict = {}
     i = 0
     for c in self.cons:
         self.cons_dict[c] = i
         i = i+1
     self.vars = list(lp.variables())
     self.numvars = len(self.vars)
     self.var_dict = {}
     #Checking for repeated names
     lp.checkDuplicateVars()
     #Creating a MOSEK environment
     self.env = mosek.Env()
     self.task = self.env.Task()
     self.task.appendcons(self.numcons)
     self.task.appendvars(self.numvars)
     if self.msg:
         self.task.set_Stream(mosek.streamtype.log,self.setOutStream)
     #Adding variables
     for i in range(self.numvars):
         vname = self.vars[i].name
         self.var_dict[vname] = i
         self.task.putvarname(i,vname)
         #Variable type (Default: Continuous)
         if self.mip & (self.vars[i].cat == constants.LpInteger):
             self.task.putvartype(i,mosek.variabletype.type_int)
             self.solution_type = mosek.soltype.itg
         #Variable bounds
         vbkey = mosek.boundkey.fr
         vup = inf
         vlow = -inf
         if self.vars[i].lowBound != None:
             vlow = self.vars[i].lowBound
             if self.vars[i].upBound != None:
                 vup = self.vars[i].upBound
                 vbkey = mosek.boundkey.ra
             else:
                 vbkey = mosek.boundkey.lo
         elif self.vars[i].upBound != None:
             vup = self.vars[i].upBound
             vbkey = mosek.boundkey.up 
         self.task.putvarbound(i,vbkey,vlow,vup)
         #Objective coefficient for the current variable.
         self.task.putcj(i,lp.objective.get(self.vars[i],0.0))
     #Coefficient matrix
     self.A_rows,self.A_cols,self.A_vals = zip(*[[self.cons_dict[row],self.var_dict[col],coeff] 
                                                 for col,row,coeff in lp.coefficients()])
     self.task.putaijlist(self.A_rows,self.A_cols,self.A_vals)
     #Constraints
     self.constraint_data_list = []
     for c in self.cons:
         cname = self.cons[c].name
         if cname != None:
             self.task.putconname(self.cons_dict[c],cname)
         else:
             self.task.putconname(self.cons_dict[c],c)
         csense = self.cons[c].sense
         cconst = -self.cons[c].constant
         clow = -inf
         cup = inf
         #Constraint bounds
         if csense == constants.LpConstraintEQ:
             cbkey = mosek.boundkey.fx
             clow = cconst
             cup = cconst
         elif csense == constants.LpConstraintGE:
             cbkey = mosek.boundkey.lo
             clow = cconst
         elif csense == constants.LpConstraintLE:
             cbkey = mosek.boundkey.up
             cup = cconst
         else:
             raise PulpSolverError('Invalid constraint type.')
         self.constraint_data_list.append([self.cons_dict[c],cbkey,clow,cup])
     self.cons_id_list,self.cbkey_list,self.clow_list,self.cup_list = zip(*self.constraint_data_list)
     self.task.putconboundlist(self.cons_id_list,self.cbkey_list,self.clow_list,self.cup_list)
     #Objective sense
     if lp.sense == constants.LpMaximize:
         self.task.putobjsense(mosek.objsense.maximize)
     else:
         self.task.putobjsense(mosek.objsense.minimize)
Exemplo n.º 2
0
def main():
    # Make mosek environment
    env = mosek.Env()

    # Create a task object and attach log stream printer
    task = env.Task(0, 0)
    task.set_Stream(mosek.streamtype.log, streamprinter)

    # Bound keys for constraints
    bkc = [mosek.boundkey.fx, mosek.boundkey.fx]

    # Bound values for constraints
    blc = [1.0, 0.5]
    buc = [1.0, 0.5]

    # Below is the sparse representation of the A
    # matrix stored by row.
    asub = [array([0]), array([1, 2])]
    aval = [array([1.0]), array([1.0, 1.0])]

    conesub = [0, 1, 2]

    barci = [0, 1, 1, 2, 2]
    barcj = [0, 0, 1, 1, 2]
    barcval = [2.0, 1.0, 2.0, 1.0, 2.0]

    barai = [array([0, 1, 2]), array([0, 1, 2, 1, 2, 2])]
    baraj = [array([0, 1, 2]), array([0, 0, 0, 1, 1, 2])]
    baraval = [array([1.0, 1.0, 1.0]), array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0])]

    numvar = 3
    numcon = len(bkc)
    BARVARDIM = [3]

    # Append 'numvar' variables.
    # The variables will initially be fixed at zero (x=0).
    task.appendvars(numvar)

    # Append 'numcon' empty constraints.
    # The constraints will initially have no bounds.
    task.appendcons(numcon)

    # Append matrix variables of sizes in 'BARVARDIM'.
    # The variables will initially be fixed at zero.
    task.appendbarvars(BARVARDIM)

    # Set the linear term c_0 in the objective.
    task.putcj(0, 1.0)

    for j in range(numvar):
        # Set the bounds on variable j
        # blx[j] <= x_j <= bux[j]
        task.putvarbound(j, mosek.boundkey.fr, -inf, +inf)

    for i in range(numcon):
        # Set the bounds on constraints.
        # blc[i] <= constraint_i <= buc[i]
        task.putconbound(i, bkc[i], blc[i], buc[i])

        # Input row i of A
        task.putarow(
            i,  # Constraint (row) index.
            asub[i],  # Column index of non-zeros in constraint j.
            aval[i])  # Non-zero values of row j.

    task.appendcone(mosek.conetype.quad, 0.0, conesub)

    symc = \
      task.appendsparsesymmat(BARVARDIM[0],
                              barci,
                              barcj,
                              barcval)

    syma0 = \
      task.appendsparsesymmat(BARVARDIM[0],
                              barai[0],
                              baraj[0],
                              baraval[0])

    syma1 = \
      task.appendsparsesymmat(BARVARDIM[0],
                              barai[1],
                              baraj[1],
                              baraval[1])

    task.putbarcj(0, [symc], [1.0])

    task.putbaraij(0, 0, [syma0], [1.0])
    task.putbaraij(1, 0, [syma1], [1.0])

    # Input the objective sense (minimize/maximize)
    task.putobjsense(mosek.objsense.minimize)

    task.writedata("sdo1.task")

    # Solve the problem and print summary
    task.optimize()
    task.solutionsummary(mosek.streamtype.msg)

    # Get status information about the solution
    prosta = task.getprosta(mosek.soltype.itr)
    solsta = task.getsolsta(mosek.soltype.itr)

    if (solsta == mosek.solsta.optimal or solsta == mosek.solsta.near_optimal):
        xx = zeros(numvar, float)
        task.getxx(mosek.soltype.itr, xx)

        lenbarvar = BARVARDIM[0] * (BARVARDIM[0] + 1) / 2
        barx = zeros(int(lenbarvar), float)
        task.getbarxj(mosek.soltype.itr, 0, barx)

        print("Optimal solution:\nx=%s\nbarx=%s" % (xx, barx))
    elif (solsta == mosek.solsta.dual_infeas_cer
          or solsta == mosek.solsta.prim_infeas_cer
          or solsta == mosek.solsta.near_dual_infeas_cer
          or solsta == mosek.solsta.near_prim_infeas_cer):
        print("Primal or dual infeasibility certificate found.\n")
    elif solsta == mosek.solsta.unknown:
        print("Unknown solution status")
    else:
        print("Other solution status")
Exemplo n.º 3
0
def mixed_integer_linear_programming(c,
                                     Aeq=None,
                                     beq=None,
                                     A=None,
                                     b=None,
                                     xmin=None,
                                     xmax=None,
                                     vtypes=None,
                                     opt=None):
    nx = c.shape[0]  # number of decision variables
    if A is not None:
        if A.shape[0] != None:
            nineq = A.shape[0]  # number of equality constraints
        else:
            nineq = 0
    else:
        nineq = 0

    if Aeq is not None:
        if Aeq.shape[0] != None:
            neq = Aeq.shape[0]  # number of inequality constraints
        else:
            neq = 0
    else:
        neq = 0
    # Fulfilling the missing informations
    if beq is None or len(beq) == 0: beq = -Inf * ones(neq)
    if b is None or len(b) == 0: b = Inf * ones(nineq)
    if xmin is None or len(xmin) == 0: xmin = -Inf * ones(nx)
    if xmax is None or len(xmax) == 0: xmax = Inf * ones(nx)

    # Make a MOSEK environment
    with mosek.Env() as env:
        # Create a task
        with env.Task(0, 0) as task:
            bkc = []
            blc = []
            buc = []
            for i in range(neq):
                bkc.append(mosek.boundkey.ra)
                blc.append(beq[i])
                buc.append(beq[i])

            for i in range(nineq):
                bkc.append(mosek.boundkey.up)
                blc.append(-Inf)
                buc.append(b[i])

            bkx = []
            blx = []
            bux = []
            for i in range(nx):
                bkx.append(mosek.boundkey.ra)
                blx.append(xmin[i])
                bux.append(xmax[i])
            if neq != 0:
                if neq != 0 and nineq != 0:
                    A = vstack([Aeq, A])
                elif neq != 0 and nineq == 0:
                    A = Aeq

            # Generate the sparse matrix
            numcon = neq + nineq
            asub = []
            aval = []
            if numcon != 0:
                for i in range(nx):
                    index = []
                    val = []
                    for j in range(numcon):
                        if A[j, i] != 0:
                            index.append(j)
                            val.append(A[j, i])

                    asub.append(index)
                    aval.append(val)
            # Append 'numcon' empty constraints.
            # The constraints will initially have no bounds.
            task.appendcons(numcon)

            # Append 'numvar' variables.
            # The variables will initially be fixed at zero (x=0).
            task.appendvars(nx)

            for j in range(nx):
                # Set the linear term c_j in the objective.
                task.putcj(j, c[j])
                # Set the bounds on variable j
                # blx[j] <= x_j <= bux[j]
                # Input column j of A
                task.putacol(
                    j,  # Variable (column) index.
                    #  Row index of non-zeros in column j.
                    asub[j],
                    aval[j])  # Non-zero Values of column j.
                if vtypes[j] == "b" or vtypes[j] == "B":
                    task.putvartypelist([j], [mosek.variabletype.type_int])
                    task.putvarbound(j, mosek.boundkey.ra, 0, 1)
                elif vtypes[j] == "c" or vtypes[j] == "C":
                    task.putvartypelist([j], [mosek.variabletype.type_int])
                    task.putvarbound(j, bkx[j], blx[j], bux[j])
                else:
                    task.putvartypelist([j], [mosek.variabletype.type_cont])
                    task.putvarbound(j, bkx[j], blx[j], bux[j])

            task.putconboundlist(range(numcon), bkc, blc, buc)

            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.minimize)

            # Optimize the task
            task.optimize()

            prosta = task.getprosta(mosek.soltype.itg)
            solsta = task.getsolsta(mosek.soltype.itg)

            # Output a solution
            xx = [0.] * nx
            task.getxx(mosek.soltype.itg, xx)
            success = 1
            if solsta in [
                    mosek.solsta.integer_optimal,
                    mosek.solsta.near_integer_optimal
            ]:
                print("Optimal solution: %s" % xx)
            elif solsta == mosek.solsta.dual_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.prim_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.near_dual_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.near_prim_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif mosek.solsta.unknown:
                if prosta == mosek.prosta.prim_infeas_or_unbounded:
                    print("Problem status Infeasible or unbounded.\n")
                elif prosta == mosek.prosta.prim_infeas:
                    print("Problem status Infeasible.\n")
                elif prosta == mosek.prosta.unkown:
                    print("Problem status unkown.\n")
                else:
                    print("Other problem status.\n")
                success = 0
            else:
                print("Other solution status")
                success = 0
            # if solsta in [mosek.solsta.integer_optimal, mosek.solsta.near_integer_optimal]:
            #     pass
            # elif solsta == mosek.solsta.dual_infeas_cer:
            #     pass
            # elif solsta == mosek.solsta.prim_infeas_cer:
            #     pass
            # elif solsta == mosek.solsta.near_dual_infeas_cer:
            #     pass
            # elif solsta == mosek.solsta.near_prim_infeas_cer:
            #     pass
            # elif mosek.solsta.unknown:
            #     if prosta == mosek.prosta.prim_infeas_or_unbounded:
            #         pass
            #     elif prosta == mosek.prosta.prim_infeas:
            #         pass
            #     elif prosta == mosek.prosta.unkown:
            #         pass
            #     else:
            #         print("Other problem status.\n")
            #     success = 0
            # else:
            #     pass
            #     success = 0

        return xx, solsta, success
Exemplo n.º 4
0
def main():
    numcon = 2
    numvar = 2

    # Since the value infinity is never used, we define
    # 'infinity' symbolic purposes only
    infinity = 0

    c = [1.0, 1.0]
    ptrb = [0, 2]
    ptre = [2, 3]
    asub = [0, 1, 0, 1]
    aval = [1.0, 1.0, 2.0, 1.0]
    bkc = [mosek.boundkey.up, mosek.boundkey.up]

    blc = [-infinity, -infinity]
    buc = [2.0, 6.0]

    bkx = [mosek.boundkey.lo, mosek.boundkey.lo]
    blx = [0.0, 0.0]

    bux = [+infinity, +infinity]
    w1 = [2.0, 6.0]
    w2 = [1.0, 0.0]
    try:
        with mosek.Env() as env:
            with env.Task(0, 0) as task:
                task.set_Stream(mosek.streamtype.log, streamprinter)
                task.inputdata(numcon, numvar, c, 0.0, ptrb, ptre, asub, aval,
                               bkc, blc, buc, bkx, blx, bux)
                task.putobjsense(mosek.objsense.maximize)
                r = task.optimize()
                if r != mosek.rescode.ok:
                    print("Mosek warning:", r)

                basis = [0] * numcon
                task.initbasissolve(basis)

                #List basis variables corresponding to columns of B
                varsub = [0, 1]

                for i in range(numcon):
                    if basis[varsub[i]] < numcon:
                        print("Basis variable no %d is xc%d" % (i, basis[i]))
                    else:
                        print("Basis variable no %d is x%d" %
                              (i, basis[i] - numcon))

                # solve Bx = w1
                # varsub contains index of non-zeros in b.
                #  On return b contains the solution x and
                # varsub the index of the non-zeros in x.
                nz = 2

                nz = task.solvewithbasis(0, nz, varsub, w1)
                print("nz = %s" % nz)
                print("Solution to Bx = w1:")

                for i in range(nz):
                    if basis[varsub[i]] < numcon:
                        print("xc %s = %s" % (basis[varsub[i]], w1[varsub[i]]))
                    else:
                        print("x%s = %s" %
                              (basis[varsub[i]] - numcon, w1[varsub[i]]))

                # Solve B^Tx = w2
                nz = 1
                varsub[0] = 0

                nz = task.solvewithbasis(1, nz, varsub, w2)

                print("Solution to B^Tx = w2:")

                for i in range(nz):
                    if basis[varsub[i]] < numcon:
                        print("xc %s = %s" % (basis[varsub[i]], w2[varsub[i]]))
                    else:
                        print("x %s = %s" %
                              (basis[varsub[i]] - numcon, w2[varsub[i]]))
    except Exception as e:
        print(e)
if __name__ == '__main__':

    n = 3
    gamma = 0.05
    mu = [0.1073, 0.0737, 0.0627]
    GT = [[0.1667, 0.0232, 0.0013], [0.0000, 0.1033, -0.0022],
          [0.0000, 0.0000, 0.0338]]
    x0 = [0.0, 0.0, 0.0]
    w = 1.0
    m = [0.01, 0.01, 0.01]

    # This value has no significance.
    inf = 0.0

    with mosek.Env() as env:
        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            rtemp = w
            for j in range(0, n):
                rtemp += x0[j]

            # Constraints.
            task.appendcons(1 + 9 * n)
            task.putconbound(0, mosek.boundkey.fx, rtemp, rtemp)
            task.putconname(0, "budget")

            task.putconboundlist(range(1 + 0, 1 + n), n * [mosek.boundkey.fx],
                                 n * [0.0], n * [0.0])
            for j in range(1, 1 + n):
Exemplo n.º 6
0
def qp(P, q, G=None, h=None, A=None, b=None, taskfile=None):
    """
    Solves a quadratic program

        minimize    (1/2)*x'*P*x + q'*x 
        subject to  G*x <= h      
                    A*x = b.                    
                    
    using MOSEK 8.0.

    solsta, x, z, y = qp(P, q, G=None, h=None, A=None, b=None, taskfile=None)

    Return values

        solsta is a MOSEK solution status key.

            If solsta is mosek.solsta.optimal,
                then (x, y, z) contains the primal-dual solution.
            If solsta is mosek.solsta.prim_infeas_cer,
                then (x, y, z) is a certificate of primal infeasibility.
            If solsta is mosek.solsta.dual_infeas_cer,
                then (x, y, z) is a certificate of dual infeasibility.
            If solsta is mosek.solsta.unknown, then (x, y, z) are all None.

            Other return values for solsta include:  
                mosek.solsta.dual_feas  
                mosek.solsta.near_dual_feas
                mosek.solsta.near_optimal
                mosek.solsta.near_prim_and_dual_feas
                mosek.solsta.near_prim_feas
                mosek.solsta.prim_and_dual_feas
                mosek.solsta.prim_feas
            in which case the (x,y,z) value may not be well-defined.
        
        x, z, y  the primal-dual solution.                    

    Options are passed to MOSEK solvers via the msk.options dictionary, 
    e.g., the following turns off output from the MOSEK solvers
    
        >>> msk.options = {mosek.iparam.log: 0} 
    
    see the MOSEK Python API manual.      
    
    Optionally, the interface can write a .task file, required for
    support questions on the MOSEK solver.
    """

    with mosek.Env() as env:

        if (type(P) is not matrix and type(P) is not spmatrix) or \
            P.typecode != 'd' or P.size[0] != P.size[1]:
            raise TypeError("'P' must be a square dense or sparse 'd' matrix ")
        n = P.size[0]

        if n < 1: raise ValueError("number of variables must be at least 1")

        if type(q) is not matrix or q.typecode != 'd' or q.size != (n, 1):
            raise TypeError("'q' must be a 'd' matrix of size (%d,1)" % n)

        if G is None: G = spmatrix([], [], [], (0, n), 'd')
        if (type(G) is not matrix and type(G) is not spmatrix) or \
            G.typecode != 'd' or G.size[1] != n:
            raise TypeError("'G' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)

        m = G.size[0]
        if h is None: h = matrix(0.0, (0, 1))
        if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1):
            raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m)

        if A is None: A = spmatrix([], [], [], (0, n), 'd')
        if (type(A) is not matrix and type(A) is not spmatrix) or \
            A.typecode != 'd' or A.size[1] != n:
            raise TypeError("'A' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        p = A.size[0]
        if b is None: b = matrix(0.0, (0, 1))
        if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1):
            raise TypeError("'b' must be a dense matrix of size (%d,1)" % p)

        if m + p is 0: raise ValueError("m + p must be greater than 0")

        c = list(q)

        bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx]
        blc = m * [-inf] + [bi for bi in b]
        buc = list(h) + list(b)

        bkx = n * [mosek.boundkey.fr]
        blx = n * [-inf]
        bux = n * [+inf]

        colptr, asub, acof = sparse([G, A]).CCS
        aptrb, aptre = colptr[:-1], colptr[1:]

        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # set MOSEK options
            for (param, val) in options.items():
                if str(param)[:6] == "iparam":
                    task.putintparam(param, val)
                elif str(param)[:6] == "dparam":
                    task.putdouparam(param, val)
                elif str(param)[:6] == "sparam":
                    task.putstrparam(param, val)
                else:
                    raise ValueError("invalid MOSEK parameter: " + str(param))

            task.inputdata(
                m + p,  # number of constraints
                n,  # number of variables
                c,  # linear objective coefficients  
                0.0,  # objective fixed value  
                list(aptrb),
                list(aptre),
                list(asub),
                list(acof),
                bkc,
                blc,
                buc,
                bkx,
                blx,
                bux)

            Ps = sparse(P)
            I, J = Ps.I, Ps.J
            tril = [k for k in range(len(I)) if I[k] >= J[k]]
            task.putqobj(list(I[tril]), list(J[tril]), list(Ps.V[tril]))

            task.putobjsense(mosek.objsense.minimize)

            if taskfile:
                task.writetask(taskfile)

            task.optimize()

            task.solutionsummary(mosek.streamtype.msg)

            solsta = task.getsolsta(mosek.soltype.itr)

            x = n * [0.0]
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, 0, n, x)
            x = matrix(x)

            if m is not 0:
                z = m * [0.0]
                task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, 0,
                                      m, z)
                z = matrix(z)
            else:
                z = matrix(0.0, (0, 1))

            if p is not 0:
                yu, yl = p * [0.0], p * [0.0]
                task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, m,
                                      m + p, yu)
                task.getsolutionslice(mosek.soltype.itr, mosek.solitem.slc, m,
                                      m + p, yl)
                y = matrix(yu) - matrix(yl)
            else:
                y = matrix(0.0, (0, 1))

    if (solsta is mosek.solsta.unknown):
        return (solsta, None, None, None)
    else:
        return (solsta, x, z, y)
Exemplo n.º 7
0
    def solve_via_data(self,
                       data,
                       warm_start,
                       verbose,
                       solver_opts,
                       solver_cache=None):
        import mosek
        env = mosek.Env()
        task = env.Task(0, 0)
        # If verbose, then set default logging parameters.
        if verbose:
            import sys

            def streamprinter(text):
                sys.stdout.write(text)
                sys.stdout.flush()

            print('\n')
            env.set_Stream(mosek.streamtype.log, streamprinter)
            task.set_Stream(mosek.streamtype.log, streamprinter)
            task.putintparam(mosek.iparam.infeas_report_auto,
                             mosek.onoffkey.on)
            task.putintparam(mosek.iparam.log_presolve, 0)

        # Parse all user-specified parameters (override default logging
        # parameters if applicable).
        kwargs = sorted(solver_opts.keys())
        save_file = None
        bfs = False
        if 'mosek_params' in kwargs:
            self._handle_mosek_params(task, solver_opts['mosek_params'])
            kwargs.remove('mosek_params')
        if 'save_file' in kwargs:
            save_file = solver_opts['save_file']
            kwargs.remove('save_file')
        if 'bfs' in kwargs:
            bfs = solver_opts['bfs']
            kwargs.remove('bfs')
        if kwargs:
            raise ValueError("Invalid keyword-argument '%s'" % kwargs[0])

        # Decide whether basis identification is needed for intpnt solver
        # This is only required if solve() was called with bfs=True
        if bfs:
            task.putintparam(mosek.iparam.intpnt_basis,
                             mosek.basindtype.always)
        else:
            task.putintparam(mosek.iparam.intpnt_basis, mosek.basindtype.never)

        # Check if the cvxpy standard form has zero variables. If so,
        # return a trivial solution. This is necessary because MOSEK
        # will crash if handed a problem with zero variables.
        if len(data[s.C]) == 0:
            return {
                s.STATUS: s.OPTIMAL,
                s.PRIMAL: [],
                s.VALUE: data[s.OFFSET],
                s.EQ_DUAL: [],
                s.INEQ_DUAL: []
            }

        # The following lines recover problem parameters, and define helper constants.
        #
        #   The problem's objective is "min c.T * z".
        #   The problem's constraint set is "G * z <=_K h."
        #   The rows in (G, h) are formatted in order of
        #       (1) linear inequalities,
        #       (2) linear equations,
        #       (3) soc constraints,
        #       (4) exponential cone constraints,
        #       (5) vectorized linear matrix inequalities.
        #   The parameter "dims" indicates the exact
        #   dimensions of each of these cones.
        #
        #   MOSEK's standard form requires that we replace generalized
        #   inequalities with slack variables and linear equations.
        #   The parameter "n" is the size of the column-vector variable
        #   after adding slacks for SOC and EXP constraints. To be
        #   consistent with MOSEK documentation, subsequent comments
        #   refer to this variable as "x".

        c = data[s.C]
        G, h = data[s.G], data[s.H]
        dims = data[s.DIMS]
        n0 = len(c)
        n = n0 + sum(dims[s.SOC_DIM]) + 3 * dims[s.EXP_DIM]
        psd_total_dims = sum(el**2 for el in dims[s.PSD_DIM])
        m = len(h)
        num_bool = len(data[s.BOOL_IDX])
        num_int = len(data[s.INT_IDX])

        # Define variables, cone constraints, and integrality constraints.
        #
        #   The variable "x" is a length-n block vector, with
        #       Block 1: "z" from "G * z <=_K h",
        #       Block 2: slacks for SOC constraints, and
        #       Block 3: slacks for EXP cone constraints.
        #
        #   Once we declare x in the MOSEK model, we add the necessary
        #   conic constraints for slack variables (Blocks 2 and 3).
        #   The last step is to add integrality constraints.
        #
        #   Note that the API call for PSD variables contains the word "bar".
        #   MOSEK documentation consistently uses "bar" as a sort of flag,
        #   indicating that a function deals with PSD variables.

        task.appendvars(n)
        task.putvarboundlist(np.arange(n, dtype=int64),
                             [mosek.boundkey.fr] * n, np.zeros(n), np.zeros(n))
        if psd_total_dims > 0:
            task.appendbarvars(dims[s.PSD_DIM])
        running_idx = n0
        for size_cone in dims[s.SOC_DIM]:
            task.appendcone(
                mosek.conetype.quad,
                0.0,  # unused
                np.arange(running_idx, running_idx + size_cone))
            running_idx += size_cone
        for k in range(dims[s.EXP_DIM]):
            task.appendcone(
                mosek.conetype.pexp,
                0.0,  # unused
                np.arange(running_idx, running_idx + 3))
            running_idx += 3
        if num_bool + num_int > 0:
            task.putvartypelist(data[s.BOOL_IDX],
                                [mosek.variabletype.type_int] * num_bool)
            task.putvarboundlist(data[s.BOOL_IDX],
                                 [mosek.boundkey.ra] * num_bool,
                                 [0] * num_bool, [1] * num_bool)
            task.putvartypelist(data[s.INT_IDX],
                                [mosek.variabletype.type_int] * num_int)

        # Define linear inequality and equality constraints.
        #
        #   Mosek will see a total of m linear expressions, which must
        #   define linear inequalities and equalities. The variable x
        #   contributes to these linear expressions by standard
        #   matrix-vector multiplication; the matrix in question is
        #   referred to as "A" in the mosek documentation. The PSD
        #   variables have a different means of contributing to the
        #   linear expressions. Specifically, a PSD variable Xj contributes
        #   "+tr( \bar{A}_{ij} * Xj )" to the i-th linear expression,
        #   where \bar{A}_{ij} is specified by a call to putbaraij.
        #
        #   The following code has three phases.
        #       (1) Build the matrix A.
        #       (2) Specify the \bar{A}_{ij} for PSD variables.
        #       (3) Specify the RHS of the m linear (in)equalities.
        #
        #   Remark : The parameter G gives every row in the first
        #   n0 columns of A. The remaining columns of A are for SOC
        #   and EXP slack variables. We can actually account for all
        #   of these slack variables at once by specifying a giant
        #   identity matrix in the appropriate position in A.

        task.appendcons(m)
        row, col, vals = sp.sparse.find(G)
        task.putaijlist(row.tolist(), col.tolist(), vals.tolist())
        total_soc_exp_slacks = sum(dims[s.SOC_DIM]) + 3 * dims[s.EXP_DIM]
        if total_soc_exp_slacks > 0:
            i = dims[s.LEQ_DIM] + dims[
                s.EQ_DIM]  # constraint index in {0, ..., m - 1}
            j = len(
                c
            )  # index of the first slack variable in the block vector "x".
            rows = np.arange(i, i + total_soc_exp_slacks).tolist()
            cols = np.arange(j, j + total_soc_exp_slacks).tolist()
            task.putaijlist(rows, cols, [1] * total_soc_exp_slacks)

        # constraint index; start of LMIs.
        i = dims[s.LEQ_DIM] + dims[s.EQ_DIM] + total_soc_exp_slacks
        for j, dim in enumerate(dims[s.PSD_DIM]):  # SDP slack variable "Xj"
            for row_idx in range(dim):
                for col_idx in range(dim):
                    val = 1. if row_idx == col_idx else 0.5
                    row = max(row_idx, col_idx)
                    col = min(row_idx, col_idx)
                    mat = task.appendsparsesymmat(dim, [row], [col], [val])
                    task.putbaraij(i, j, [mat], [1.0])
                    i += 1

        num_eq = len(h) - dims[s.LEQ_DIM]
        type_constraint = [mosek.boundkey.up] * dims[s.LEQ_DIM] + \
                          [mosek.boundkey.fx] * num_eq
        task.putconboundlist(np.arange(m, dtype=int), type_constraint, h, h)

        # Define the objective, and optimize the mosek task.

        task.putclist(np.arange(len(c)), c)
        task.putobjsense(mosek.objsense.minimize)
        if save_file:
            task.writedata(save_file)
        task.optimize()

        if verbose:
            task.solutionsummary(mosek.streamtype.msg)

        return {'env': env, 'task': task, 'solver_options': solver_opts}
Exemplo n.º 8
0
def main():
    # Make a MOSEK environment
    env = mosek.Env()
    # Attach a printer to the environment
    env.set_Stream(mosek.streamtype.log, streamprinter)
    # Create a task
    task = env.Task(0, 0)
    # Attach a printer to the task
    task.set_Stream(mosek.streamtype.log, streamprinter)
    # Bound keys for constraints
    bkc = [mosek.boundkey.fx, mosek.boundkey.lo, mosek.boundkey.up]
    # Bound values for constraints
    blc = [30.0, 15.0, -inf]
    buc = [30.0, +inf, 25.0]
    # Bound keys for variables
    bkx = [
        mosek.boundkey.lo, mosek.boundkey.ra, mosek.boundkey.lo,
        mosek.boundkey.lo
    ]
    # Bound values for variables
    blx = [0.0, 0.0, 0.0, 0.0]
    bux = [+inf, 10.0, +inf, +inf]
    # Objective coefficients

    c = [3.0, 1.0, 5.0, 1.0]

    # Below is the sparse representation of the A
    # matrix stored by column.
    asub = [array([0, 1]), array([0, 1, 2]), array([0, 1]), array([1, 2])]
    aval = [
        array([3.0, 2.0]),
        array([1.0, 1.0, 2.0]),
        array([2.0, 3.0]),
        array([1.0, 3.0])
    ]
    NUMVAR = len(bkx)
    NUMCON = len(bkc)
    NUMANZ = 9
    # Give MOSEK an estimate of the size of the input data.
    #  This is done to increase the speed of inputting data.
    #  However, it is optional.
    task.putmaxnumvar(NUMVAR)
    task.putmaxnumcon(NUMCON)
    task.putmaxnumanz(NUMANZ)
    # Append 'NUMCON' empty constraints.
    # The constraints will initially have no bounds.
    task.append(mosek.accmode.con, NUMCON)

    #Append 'NUMVAR' variables.
    # The variables will initially be fixed at zero (x=0).
    task.append(mosek.accmode.var, NUMVAR)

    #Optionally add a constant term to the objective.
    task.putcfix(0.0)

    for j in range(NUMVAR):
        # Set the linear term c_j in the objective.
        task.putcj(j, c[j])
        # Set the bounds on variable j
        # blx[j] <= x_j <= bux[j]
        task.putbound(mosek.accmode.var, j, bkx[j], blx[j], bux[j])
        # Input column j of A
        task.putavec(
            mosek.accmode.var,  # Input columns of A.
            j,  # Variable (column) index.
            asub[j],  # Row index of non-zeros in column j.
            aval[j])  # Non-zero Values of column j.
    for i in range(NUMCON):
        task.putbound(mosek.accmode.con, i, bkc[i], blc[i], buc[i])
    # Input the objective sense (minimize/maximize)
    task.putobjsense(mosek.objsense.maximize)

    # Optimize the task
    task.optimize()

    # Print a summary containing information
    # about the solution for debugging purposes
    task.solutionsummary(mosek.streamtype.msg)

    prosta = []
    solsta = []
    [prosta, solsta] = task.getsolutionstatus(mosek.soltype.bas)
    # Output a solution
    xx = zeros(NUMVAR, float)
    task.getsolutionslice(mosek.soltype.bas, mosek.solitem.xx, 0, NUMVAR, xx)
    if solsta == mosek.solsta.optimal or solsta == mosek.solsta.near_optimal:
        print("Optimal solution: %s" % xx)
    elif solsta == mosek.solsta.dual_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.prim_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.near_dual_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.near_prim_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif mosek.solsta.unknown:
        print("Unknown solution status")
    else:
        print("Other solution status")
Exemplo n.º 9
0
def optimize(*, c, A, k, p_idxs, **kwargs):
    # pylint: disable=too-many-locals,too-many-statements,too-many-branches
    """
    Definitions
    -----------
    "[a,b] array of floats" indicates array-like data with shape [a,b]
    n is the number of monomials in the gp
    m is the number of variables in the gp
    p is the number of posynomial constraints in the gp

    Arguments
    ---------
    c : floats array of shape n
        Coefficients of each monomial
    A : gpkit.small_classes.CootMatrix, of shape (n, m)
        Exponents of the various free variables for each monomial.
    k : ints array of shape p+1
        k[0] is the number of monomials (rows of A) present in the objective
        k[1:] is the number of monomials (rows of A) present in each constraint
    p_idxs : ints array of shape n.
        sel = p_idxs == i selects rows of A
                          and entries of c of the i-th posynomial
        fi(x) = c[sel] @ exp(A[sel,:] @ x).
                The 0-th posynomial gives the objective function, and the
                remaining posynomials should be constrained to be <= 1.

    Returns
    -------
    dict
        Contains the following keys
            "status": string
                "optimal", "infeasible", "unbounded", or "unknown".
            "primal" np.ndarray or None
                The values of the ``m`` primal variables.
            "la": np.ndarray or None
                The dual variables to the ``p`` posynomial constraints, when
                those constraints are represented in log-sum-exp ("LSE") form.
    """
    #
    #   Initial transformations of problem data.
    #
    #       separate monomial constraints (call them "lin"),
    #       from those which require
    #       an LSE representation (call those "lse").
    #
    #       NOTE: the epigraph of the objective function always gets an "lse"
    #       representation, even if the objective is a monomial.
    #
    log_c = np.log(np.array(c))
    lse_posys = [0]
    lin_posys = []
    for i, val in enumerate(k[1:]):
        if val > 1:
            lse_posys.append(i + 1)
        else:
            lin_posys.append(i + 1)
    if lin_posys:
        A = A.tocsr()
        lin_posys_set = frozenset(lin_posys)
        lin_idxs = [i for i, p in enumerate(p_idxs) if p in lin_posys_set]
        lse_idxs = np.ones(A.shape[0], dtype=bool)
        lse_idxs[lin_idxs] = False
        A_lse = A[lse_idxs, :].tocoo()
        log_c_lse = log_c[lse_idxs]
        A_lin = A[lin_idxs, :].tocoo()
        log_c_lin = log_c[lin_idxs]
    else:
        log_c_lin = None  # A_lin won't be referenced later,
        A_lse = A  # so no need to define it.
        log_c_lse = log_c
    k_lse = [k[i] for i in lse_posys]
    n_lse = sum(k_lse)
    p_lse = len(k_lse)
    lse_p_idx = []
    for i, ki in enumerate(k_lse):
        lse_p_idx.extend([i] * ki)
    lse_p_idx = np.array(lse_p_idx)
    #
    #   Create MOSEK task. Add variables, bound constraints, and conic
    #   constraints.
    #
    #       Say that MOSEK's optimization variable is a block vector,
    #       [x;t;z], where ...
    #           x is the user-defined primal variable (length m),
    #           t is an aux variable for exponential cones (length 3 * n_lse),
    #           z is an epigraph variable for LSE terms (length p_lse).
    #
    #       The variable z[0] is special,
    #       because it's the epigraph of the objective function
    #       in LSE form. The sign of this variable is not constrained.
    #
    #       The variables z[1:] are epigraph terms for "log",
    #       in constraints that naturally write as
    #       LSE(Ai @ x + log_ci) <= 0. These variables need to be <= 0.
    #
    #       The main constraints on (x, t, z) are described
    #       in next comment block.
    #
    env = mosek.Env()
    task = env.Task(0, 0)
    m = A.shape[1]
    msk_nvars = m + 3 * n_lse + p_lse
    task.appendvars(msk_nvars)
    # "x" is free
    task.putvarboundlist(np.arange(m), [mosek.boundkey.fr] * m, np.zeros(m),
                         np.zeros(m))
    # t[3 * i + i] == 1, other components are free.
    bound_types = [mosek.boundkey.fr, mosek.boundkey.fx, mosek.boundkey.fr]
    task.putvarboundlist(np.arange(m, m + 3 * n_lse), bound_types * n_lse,
                         np.ones(3 * n_lse), np.ones(3 * n_lse))
    # z[0] is free; z[1:] <= 0.
    bound_types = [mosek.boundkey.fr] + [mosek.boundkey.up] * (p_lse - 1)
    task.putvarboundlist(np.arange(m + 3 * n_lse, msk_nvars), bound_types,
                         np.zeros(p_lse), np.zeros(p_lse))
    # t[3*i], t[3*i + 1], t[3*i + 2] belongs to the exponential cone
    task.appendconesseq([mosek.conetype.pexp] * n_lse, [0.0] * n_lse,
                        [3] * n_lse, m)
    #
    #   Exponential cone affine constraints (other than t[3*i + 1] == 1).
    #
    #       For each i in {0, ..., n_lse - 1}, we need
    #           t[3*i + 2] == A_lse[i, :] @ x + log_c_lse[i] - z[lse_p_idx[i]].
    #
    #       For each j from {0, ..., p_lse - 1}, the "t" should also satisfy
    #           sum(t[3*i] for i where i == lse_p_idx[j]) <= 1.
    #
    #       When combined with bound constraints ``t[3*i + 1] == 1``, the
    #       above constraints imply
    #           LSE(A_lse[sel, :] @ x + log_c_lse[sel]) <= z[i]
    #       for ``sel = lse_p_idx == i``.
    #
    task.appendcons(n_lse + p_lse)
    # Linear equations between (x,t,z).
    #   start with coefficients on "x"
    rows = list(A_lse.row)
    cols = list(A_lse.col)
    vals = list(A_lse.data)
    #   add coefficients on "t"
    rows += list(range(n_lse))
    cols += (m + 3 * np.arange(n_lse) + 2).tolist()
    vals += [-1.0] * n_lse
    #   add coefficients on "z"
    rows += list(range(n_lse))
    cols += [m + 3 * n_lse + lse_p_idx[i] for i in range(n_lse)]
    vals += [-1.0] * n_lse
    task.putaijlist(rows, cols, vals)
    cur_con_idx = n_lse
    # Linear inequalities on certain sums of "t".
    rows, cols, vals = [], [], []
    for i in range(p_lse):
        sels = np.nonzero(lse_p_idx == i)[0]
        rows.extend([cur_con_idx] * sels.size)
        cols.extend(m + 3 * sels)
        vals.extend([1] * sels.size)
        cur_con_idx += 1
    task.putaijlist(rows, cols, vals)
    # Build the right-hand-sides of the [in]equality constraints
    type_constraint = [mosek.boundkey.fx] * n_lse + [mosek.boundkey.up] * p_lse
    h = np.concatenate([-log_c_lse, np.ones(p_lse)])
    task.putconboundlist(np.arange(h.size, dtype=int), type_constraint, h, h)
    #
    #   Affine constraints, not needing the exponential cone
    #
    #       Require A_lin @ x <= -log_c_lin.
    #
    if log_c_lin is not None:
        task.appendcons(log_c_lin.size)
        rows = cur_con_idx + np.array(A_lin.row)
        task.putaijlist(rows, A_lin.col, A_lin.data)
        type_constraint = [mosek.boundkey.up] * log_c_lin.size
        con_indices = np.arange(cur_con_idx, cur_con_idx + log_c_lin.size)
        h = -log_c_lin  #pylint: disable=invalid-unary-operand-type
        task.putconboundlist(con_indices, type_constraint, h, h)
        cur_con_idx += log_c_lin.size
    #
    #   Set the objective function
    #
    task.putclist([int(m + 3 * n_lse)], [1])
    task.putobjsense(mosek.objsense.minimize)
    #
    #   Set solver parameters, and call .solve().
    #
    verbose = kwargs.get("verbose", True)
    if verbose:

        def streamprinter(text):
            "Stream printer for output from mosek."
            print(text)

        env.set_Stream(mosek.streamtype.log, streamprinter)
        task.set_Stream(mosek.streamtype.log, streamprinter)
        task.putintparam(mosek.iparam.infeas_report_auto, mosek.onoffkey.on)
        task.putintparam(mosek.iparam.log_presolve, 0)

    try:
        task.optimize()
    except mosek.Error as e:  # pragma: no cover
        if e.errno in [
                mosek.rescode.err_missing_license_file,
                mosek.rescode.err_license_version,
                mosek.rescode.err_license_expired
        ]:
            raise InvalidLicense() from e
        raise e

    if verbose:
        task.solutionsummary(mosek.streamtype.msg)
    #
    #   Recover the solution
    #
    msk_solsta = task.getsolsta(mosek.soltype.itr)
    if msk_solsta == mosek.solsta.prim_infeas_cer:
        raise PrimalInfeasible()
    if msk_solsta == mosek.solsta.dual_infeas_cer:
        raise DualInfeasible()
    if msk_solsta != mosek.solsta.optimal:  # pragma: no cover
        raise UnknownInfeasible("solution status: ", msk_solsta)

    # recover primal variables
    x = [0.] * m
    task.getxxslice(mosek.soltype.itr, 0, m, x)
    # recover dual variables for log-sum-exp epigraph constraints
    # (skip epigraph of the objective function).
    z_duals = [0.] * (p_lse - 1)
    task.getsuxslice(mosek.soltype.itr, m + 3 * n_lse + 1, msk_nvars, z_duals)
    z_duals = np.array(z_duals)
    z_duals[z_duals < 0] = 0
    # recover dual variables for the remaining user-provided constraints
    if log_c_lin is not None:
        aff_duals = [0.] * log_c_lin.size
        task.getsucslice(mosek.soltype.itr, n_lse + p_lse, cur_con_idx,
                         aff_duals)
        aff_duals = np.array(aff_duals)
        aff_duals[aff_duals < 0] = 0
        # merge z_duals with aff_duals
        merged_duals = np.zeros(len(k))
        merged_duals[lse_posys[1:]] = z_duals  # skipping the cost
        merged_duals[lin_posys] = aff_duals
        merged_duals = merged_duals[1:]
    else:
        merged_duals = z_duals
    # wrap things up in a dictionary
    solution = {
        "status": "optimal",
        "primal": np.array(x),
        "la": merged_duals,
        "objective": np.exp(task.getprimalobj(mosek.soltype.itr))
    }
    task.__exit__(None, None, None)
    env.__exit__(None, None, None)
    return solution
Exemplo n.º 10
0
class MOSEK(LpSolver):
    """Mosek lp and mip solver (via Mosek Optimizer API)."""

    name = "MOSEK"
    try:
        global mosek
        import mosek

        env = mosek.Env()
    except ImportError:

        def available(self):
            """True if Mosek is available."""
            return False

        def actualSolve(self, lp, callback=None):
            """Solves a well-formulated lp problem."""
            raise PulpSolverError("MOSEK : Not Available")

    else:

        def __init__(
            self,
            mip=True,
            msg=True,
            options={},
            task_file_name="",
            sol_type=mosek.soltype.bas,
        ):
            """Initializes the Mosek solver.

            Keyword arguments:

            @param mip: If False, then solve MIP as LP.

            @param msg: Enable Mosek log output.

            @param options: Accepts a dictionary of Mosek solver parameters. Ignore to
                            use default parameter values. Eg: options = {mosek.dparam.mio_max_time:30}
                            sets the maximum time spent by the Mixed Integer optimizer to 30 seconds.
                            Equivalently, one could also write: options = {"MSK_DPAR_MIO_MAX_TIME":30}
                            which uses the generic parameter name as used within the solver, instead of
                            using an object from the Mosek Optimizer API (Python), as before.

            @param task_file_name: Writes a Mosek task file of the given name. By default,
                            no task file will be written. Eg: task_file_name = "eg1.opf".

            @param sol_type: Mosek supports three types of solutions: mosek.soltype.bas
                            (Basic solution, default), mosek.soltype.itr (Interior-point
                            solution) and mosek.soltype.itg (Integer solution).

            For a full list of Mosek parameters (for the Mosek Optimizer API) and supported task file
            formats, please see https://docs.mosek.com/9.1/pythonapi/parameters.html#doc-all-parameter-list.
            """
            self.mip = mip
            self.msg = msg
            self.task_file_name = task_file_name
            self.solution_type = sol_type
            self.options = options

        def available(self):
            """True if Mosek is available."""
            return True

        def setOutStream(self, text):
            """Sets the log-output stream."""
            sys.stdout.write(text)
            sys.stdout.flush()

        def buildSolverModel(self, lp, inf=1e20):
            """Translate the problem into a Mosek task object."""
            self.cons = lp.constraints
            self.numcons = len(self.cons)
            self.cons_dict = {}
            i = 0
            for c in self.cons:
                self.cons_dict[c] = i
                i = i + 1
            self.vars = list(lp.variables())
            self.numvars = len(self.vars)
            self.var_dict = {}
            # Checking for repeated names
            lp.checkDuplicateVars()
            self.task = MOSEK.env.Task()
            self.task.appendcons(self.numcons)
            self.task.appendvars(self.numvars)
            if self.msg:
                self.task.set_Stream(mosek.streamtype.log, self.setOutStream)
            # Adding variables
            for i in range(self.numvars):
                vname = self.vars[i].name
                self.var_dict[vname] = i
                self.task.putvarname(i, vname)
                # Variable type (Default: Continuous)
                if self.mip & (self.vars[i].cat == constants.LpInteger):
                    self.task.putvartype(i, mosek.variabletype.type_int)
                    self.solution_type = mosek.soltype.itg
                # Variable bounds
                vbkey = mosek.boundkey.fr
                vup = inf
                vlow = -inf
                if self.vars[i].lowBound != None:
                    vlow = self.vars[i].lowBound
                    if self.vars[i].upBound != None:
                        vup = self.vars[i].upBound
                        vbkey = mosek.boundkey.ra
                    else:
                        vbkey = mosek.boundkey.lo
                elif self.vars[i].upBound != None:
                    vup = self.vars[i].upBound
                    vbkey = mosek.boundkey.up
                self.task.putvarbound(i, vbkey, vlow, vup)
                # Objective coefficient for the current variable.
                self.task.putcj(i, lp.objective.get(self.vars[i], 0.0))
            # Coefficient matrix
            self.A_rows, self.A_cols, self.A_vals = zip(
                *[
                    [self.cons_dict[row], self.var_dict[col], coeff]
                    for col, row, coeff in lp.coefficients()
                ]
            )
            self.task.putaijlist(self.A_rows, self.A_cols, self.A_vals)
            # Constraints
            self.constraint_data_list = []
            for c in self.cons:
                cname = self.cons[c].name
                if cname != None:
                    self.task.putconname(self.cons_dict[c], cname)
                else:
                    self.task.putconname(self.cons_dict[c], c)
                csense = self.cons[c].sense
                cconst = -self.cons[c].constant
                clow = -inf
                cup = inf
                # Constraint bounds
                if csense == constants.LpConstraintEQ:
                    cbkey = mosek.boundkey.fx
                    clow = cconst
                    cup = cconst
                elif csense == constants.LpConstraintGE:
                    cbkey = mosek.boundkey.lo
                    clow = cconst
                elif csense == constants.LpConstraintLE:
                    cbkey = mosek.boundkey.up
                    cup = cconst
                else:
                    raise PulpSolverError("Invalid constraint type.")
                self.constraint_data_list.append([self.cons_dict[c], cbkey, clow, cup])
            self.cons_id_list, self.cbkey_list, self.clow_list, self.cup_list = zip(
                *self.constraint_data_list
            )
            self.task.putconboundlist(
                self.cons_id_list, self.cbkey_list, self.clow_list, self.cup_list
            )
            # Objective sense
            if lp.sense == constants.LpMaximize:
                self.task.putobjsense(mosek.objsense.maximize)
            else:
                self.task.putobjsense(mosek.objsense.minimize)

        def findSolutionValues(self, lp):
            """
            Read the solution values and status from the Mosek task object. Note: Since the status
            map from mosek.solsta to LpStatus is not exact, it is recommended that one enables the
            log output and then refer to Mosek documentation for a better understanding of the
            solution (especially in the case of mip problems).
            """
            self.solsta = self.task.getsolsta(self.solution_type)
            self.solution_status_dict = {
                mosek.solsta.optimal: constants.LpStatusOptimal,
                mosek.solsta.prim_infeas_cer: constants.LpStatusInfeasible,
                mosek.solsta.dual_infeas_cer: constants.LpStatusUnbounded,
                mosek.solsta.unknown: constants.LpStatusUndefined,
                mosek.solsta.integer_optimal: constants.LpStatusOptimal,
                mosek.solsta.prim_illposed_cer: constants.LpStatusNotSolved,
                mosek.solsta.dual_illposed_cer: constants.LpStatusNotSolved,
                mosek.solsta.prim_feas: constants.LpStatusNotSolved,
                mosek.solsta.dual_feas: constants.LpStatusNotSolved,
                mosek.solsta.prim_and_dual_feas: constants.LpStatusNotSolved,
            }
            # Variable values.
            try:
                self.xx = [0.0] * self.numvars
                self.task.getxx(self.solution_type, self.xx)
                for var in lp.variables():
                    var.varValue = self.xx[self.var_dict[var.name]]
            except mosek.Error:
                pass
            # Constraint slack variables.
            try:
                self.xc = [0.0] * self.numcons
                self.task.getxc(self.solution_type, self.xc)
                for con in lp.constraints:
                    lp.constraints[con].slack = -(
                        self.cons[con].constant + self.xc[self.cons_dict[con]]
                    )
            except mosek.Error:
                pass
            # Reduced costs.
            if self.solution_type != mosek.soltype.itg:
                try:
                    self.x_rc = [0.0] * self.numvars
                    self.task.getreducedcosts(
                        self.solution_type, 0, self.numvars, self.x_rc
                    )
                    for var in lp.variables():
                        var.dj = self.x_rc[self.var_dict[var.name]]
                except mosek.Error:
                    pass
                # Constraint Pi variables.
                try:
                    self.y = [0.0] * self.numcons
                    self.task.gety(self.solution_type, self.y)
                    for con in lp.constraints:
                        lp.constraints[con].pi = self.y[self.cons_dict[con]]
                except mosek.Error:
                    pass

        def putparam(self, par, val):
            """
            Pass the values of valid parameters to Mosek.
            """
            if isinstance(par, mosek.dparam):
                self.task.putdouparam(par, val)
            elif isinstance(par, mosek.iparam):
                self.task.putintparam(par, val)
            elif isinstance(par, mosek.sparam):
                self.task.putstrparam(par, val)
            elif isinstance(par, str):
                if par.startswith("MSK_DPAR_"):
                    self.task.putnadouparam(par, val)
                elif par.startswith("MSK_IPAR_"):
                    self.task.putnaintparam(par, val)
                elif par.startswith("MSK_SPAR_"):
                    self.task.putnastrparam(par, val)
                else:
                    raise PulpSolverError(
                        "Invalid MOSEK parameter: '{}'. Check MOSEK documentation for a list of valid parameters.".format(
                            par
                        )
                    )

        def actualSolve(self, lp):
            """
            Solve a well-formulated lp problem.
            """
            self.buildSolverModel(lp)
            # Set solver parameters
            for msk_par in self.options:
                self.putparam(msk_par, self.options[msk_par])
            # Task file
            if self.task_file_name:
                self.task.writedata(self.task_file_name)
            # Optimize
            self.task.optimize()
            # Mosek solver log (default: standard output stream)
            if self.msg:
                self.task.solutionsummary(mosek.streamtype.msg)
            self.findSolutionValues(lp)
            lp.assignStatus(self.solution_status_dict[self.solsta])
            for var in lp.variables():
                var.modified = False
            for con in lp.constraints.values():
                con.modified = False
            return lp.status

        def actualResolve(self, lp, inf=1e20, **kwargs):
            """
            Modify constraints and re-solve an lp. The Mosek task object created in the first solve is used.
            """
            for c in self.cons:
                if self.cons[c].modified:
                    csense = self.cons[c].sense
                    cconst = -self.cons[c].constant
                    clow = -inf
                    cup = inf
                    # Constraint bounds
                    if csense == constants.LpConstraintEQ:
                        cbkey = mosek.boundkey.fx
                        clow = cconst
                        cup = cconst
                    elif csense == constants.LpConstraintGE:
                        cbkey = mosek.boundkey.lo
                        clow = cconst
                    elif csense == constants.LpConstraintLE:
                        cbkey = mosek.boundkey.up
                        cup = cconst
                    else:
                        raise PulpSolverError("Invalid constraint type.")
                    self.task.putconbound(self.cons_dict[c], cbkey, clow, cup)
            # Re-solve
            self.task.optimize()
            self.findSolutionValues(lp)
            lp.assignStatus(self.solution_status_dict[self.solsta])
            for var in lp.variables():
                var.modified = False
            for con in lp.constraints.values():
                con.modified = False
            return lp.status
Exemplo n.º 11
0
    def solve(self, p):

        # Get problem dimensions
        n = p.P.shape[0]
        m = p.A.shape[0]
        '''
        Load problem
        '''
        # Create environment
        env = mosek.Env()

        # Create optimization task
        task = env.Task()

        if self.options['verbose']:
            # Define a stream printer to grab output from MOSEK
            def streamprinter(text):
                import sys
                sys.stdout.write(text)
                sys.stdout.flush()

            env.set_Stream(mosek.streamtype.log, streamprinter)
            task.set_Stream(mosek.streamtype.log, streamprinter)

        # Load problem into task object

        # Append 'm' empty constraints.
        # The constraints will initially have no bounds.
        task.appendcons(m)

        # Append 'n' variables.
        # The variables will initially be fixed at zero (x=0).
        task.appendvars(n)

        # Add linear cost by iterating over all variables
        for j in range(n):
            task.putcj(j, p.q[j])
            task.putvarbound(j, mosek.boundkey.fr, -np.inf, np.inf)

        # Constrain integer variables if present
        if p.i_idx is not None:
            int_types = [mosek.variabletype.type_int] * len(p.i_idx)
            int_idx = p.i_idx.tolist()
            task.putvartypelist(int_idx, int_types)

            for i in range(len(p.i_idx)):
                if p.i_l is None and p.i_u is not None:
                    task.putvarbound(p.i_idx[i], mosek.boundkey.up, 0,
                                     p.i_u[i])
                elif p.i_l is not None and p.i_u is None:
                    task.putvarbound(p.i_idx[i], mosek.boundkey.lo, p.i_l[i],
                                     0)
                elif p.i_l is not None and p.i_u is not None:
                    task.putvarbound(p.i_idx[i], mosek.boundkey.ra, p.i_l[i],
                                     p.i_u[i])

        # Add constraints
        if p.A is not None:
            row_A, col_A, el_A = spa.find(p.A)
            task.putaijlist(row_A, col_A, el_A)

            for j in range(m):
                # Get bounds and keys
                u_temp = p.u[j] if p.u[j] < 1e20 else np.inf
                l_temp = p.l[j] if p.l[j] > -1e20 else -np.inf

                # Divide 5 cases
                if (np.abs(l_temp - u_temp) < 1e-08):
                    bound_key = mosek.boundkey.fx
                elif l_temp == -np.inf and u_temp == np.inf:
                    bound_key = mosek.boundkey.fr
                elif l_temp != -np.inf and u_temp == np.inf:
                    bound_key = mosek.boundkey.lo
                elif l_temp != -np.inf and u_temp != np.inf:
                    bound_key = mosek.boundkey.ra
                elif l_temp == -np.inf and u_temp != np.inf:
                    bound_key = mosek.boundkey.up

                # Add bound
                task.putconbound(j, bound_key, l_temp, u_temp)

        # Add quadratic cost
        if p.P.count_nonzero():  # If there are any nonzero elms in P
            P = spa.tril(p.P, format='coo')
            task.putqobj(P.row, P.col, P.data)

        # Set problem minimization
        task.putobjsense(mosek.objsense.minimize)
        '''
        Set parameters
        '''
        for param, value in self.options.items():
            if param == 'verbose':
                if value is False:
                    self._handle_str_param(task, 'MSK_IPAR_LOG'.strip(), 0)
            else:
                if isinstance(param, str):
                    self._handle_str_param(task, param.strip(), value)
                else:
                    self._handle_enum_param(task, param, value)
        '''
        Solve problem
        '''
        try:
            # Optimization and check termination code
            trmcode = task.optimize()
        except:
            if self.options['verbose']:
                print("Error in MOSEK solution\n")
            return QuadprogResults(qp.SOLVER_ERROR, None, None, None, np.inf,
                                   None)

        if self.options['verbose']:
            task.solutionsummary(mosek.streamtype.msg)
        '''
        Extract results
        '''

        # Get solution type and status
        soltype, solsta = self.choose_solution(task)

        # Map status using statusmap
        status = self.STATUS_MAP.get(solsta, qp.SOLVER_ERROR)

        # Get statistics
        cputime = task.getdouinf(mosek.dinfitem.optimizer_time) + \
            task.getdouinf(mosek.dinfitem.presolve_time)
        total_iter = task.getintinf(mosek.iinfitem.intpnt_iter)

        if status in qp.SOLUTION_PRESENT:
            # get primal variables values
            sol = np.zeros(task.getnumvar())
            task.getxx(soltype, sol)
            # get obj value
            objval = task.getprimalobj(soltype)
            # get dual
            if p.i_idx is None:
                dual = np.zeros(task.getnumcon())
                task.gety(soltype, dual)
                # it appears signs are inverted
                dual = -dual
            else:
                dual = None

            return QuadprogResults(status, objval, sol, dual, cputime,
                                   total_iter)
        else:
            return QuadprogResults(status, None, None, None, cputime, None)
Exemplo n.º 12
0
    def get_safe_action(self, observation, action, environment):
        flag = True
        landmark_near = []
        for i, landmark in enumerate(environment.world.landmarks[0:-1]):
            dist = np.sqrt(np.sum(np.square(environment.world.policy_agents[0].state.p_pos - landmark.state.p_pos))) \
                   - (environment.world.policy_agents[0].size + landmark.size) - 0.044
            if dist <= 0:
                landmark_near.append(landmark)
                flag = False
        if flag:
            return action, False

        x = observation[1]
        y = observation[2]
        V = observation[0]
        theta = observation[3]
        omega = observation[4]
        # print(theta)
        d_omega = action[3] - action[4]
        dt = environment.world.dt
        a1 = x + V * np.cos(theta) * dt + theta * V * np.sin(theta) * dt
        b1 = -V * np.sin(theta) * dt
        a2 = y + V * np.sin(theta) * dt - theta * V * np.cos(theta) * dt
        b2 = V * np.cos(theta) * dt
        c1 = a1 + b1 * theta
        d1 = b1 * dt
        c2 = a2 + b2 * theta
        d2 = b2 * dt
        e1 = -2 * x * c1
        f1 = -2 * x * d1
        e2 = -2 * y * c2
        f2 = -2 * y * d2

        flag = True
        for _, landmark in enumerate(landmark_near):
            self.R = landmark.size + 0.5 * environment.world.policy_agents[
                0].size
            x0 = landmark.state.p_pos[0]
            y0 = landmark.state.p_pos[1]
            landmark0 = landmark

            g = d1 * d1 + d2 * d2
            h = 2 * c1 * d1 + 2 * c2 * d2 + f1 + f2
            i = c1 * c1 + c2 * c2 + e1 + e2 + np.square(landmark0.state.p_pos[0]) + \
                np.square(landmark0.state.p_pos[1])
            lower_c = np.square(landmark0.size + 0.01)
            upper_c = inf
            A = landmark0.state.p_pos[0] - x
            B = landmark0.state.p_pos[1] - y
            C = - (landmark0.state.p_pos[0]) * x \
                + np.square(x) \
                - (landmark0.state.p_pos[1]) * y \
                + np.square(y)

            # solve x3
            self.x0 = np.array([x, y])
            self.x1 = np.array([x0, y0])
            args = [
                np.square(self.x1[1] - self.x0[1]) +
                np.square(self.x1[0] - self.x0[0]),
                2 * (self.x1[1] - self.x0[1]) * np.square(self.R),
                np.square(np.square(self.R)) -
                np.square(self.R) * np.square(self.x1[0] - self.x0[0])
            ]
            root = np.roots(args)
            y3_0 = root[0] + self.x1[1]
            y3_1 = root[1] + self.x1[1]
            x3_0 = (-(y3_0 - self.x1[1]) * (self.x1[1] - self.x0[1]) - np.square(self.R))/(self.x1[0] - self.x0[0]) + \
                    self.x1[0]
            x3_1 = (-(y3_1 - self.x1[1]) * (self.x1[1] - self.x0[1]) - np.square(self.R)) / (self.x1[0] - self.x0[0]) + \
                    self.x1[0]

            x3 = np.array([x3_0, y3_0])
            temp1 = ((y - y0) * c1 - (x - x0) * c2 - y * x0 + y0 * x) \
                    * ((y - y0) * x3[0] - (x - x0) * x3[1] - y * x0 + y0 * x)
            x3 = np.array([x3_1, y3_1])
            x3 = np.array([x3_0, y3_0]) if temp1 > 0 else np.array(
                [x3_1, y3_1])
            x3[0] = 1.1 * x3[0] - 0.1 * self.x1[0]
            x3[1] = 1.1 * x3[1] - 0.1 * self.x1[1]
            '''print(((y - y0) * c1 - (x - x0) * d1 - y * x0 + y0 * x)
                  * ((y - y0) * x3[0] - (x - x0) * x3[1] - y * x0 + y0 * x))
            print((x3[0] - self.x0[0]) * (x3[0] - self.x1[0]) + (x3[1] - self.x0[1]) * (x3[1] - self.x1[1]))
            print((x3[0] - self.x1[0]) * (x3[0] - self.x1[0]) + (x3[1] - self.x1[1]) * (x3[1] - self.x1[1]) - self.R * self.R)'''
            temp2 = ((x3[1] - self.x0[1]) * self.x1[0] - (x3[0] - self.x0[0]) * self.x1[1] + self.x0[1] * x3[0] - self.x0[0] * x3[1]) \
                    * ((x3[1] - self.x0[1]) * c1 - (x3[0] - self.x0[0]) * c2 + self.x0[1] * x3[0] - self.x0[0] * x3[1])
            k1 = temp2 * (x3[1] - self.x0[1])
            k2 = temp2 * (x3[0] - self.x0[0])
            k3 = temp2 * (self.x0[1] * x3[0] - self.x0[0] * x3[1])
            dist = np.sqrt(np.sum(np.square(environment.world.landmarks[-1].state.p_pos - landmark.state.p_pos))) \
                   - (environment.world.landmarks[-1].size + 1.2 * landmark.size)
            if temp2 > 0:
                flag = False
                break
        if flag:
            return action, False
        self.num_call = self.num_call + 1

        # Make a MOSEK environment
        with mosek.Env() as env:
            # Attach a printer to the environment
            # env.set_Stream(mosek.streamtype.log, streamprinter)

            # Create a task
            with env.Task(0, 0) as task:
                # task.set_Stream(mosek.streamtype.log, streamprinter)
                # Set up and input bounds and linear coefficients
                bkc = [mosek.boundkey.up]
                blc = [-inf]
                buc = [-k3 - k1 * c1 + k2 * c2]
                numvar = 1
                bkx = [mosek.boundkey.fr] * numvar
                blx = [-inf] * numvar
                bux = [inf] * numvar
                temp = 0.12
                c = [-2.0 * omega - 2 * dt * d_omega]
                asub = [[0]]
                aval = [[k1 * d1 - k2 * d2]]

                numvar = len(bkx)
                numcon = len(bkc)

                # Append 'numcon' empty constraints.
                # The constraints will initially have no bounds.
                task.appendcons(numcon)

                # Append 'numvar' variables.
                # The variables will initially be fixed at zero (x=0).
                task.appendvars(numvar)

                for j in range(numvar):
                    # Set the linear term c_j in the objective.
                    task.putcj(j, c[j])
                    # Set the bounds on variable j
                    # blx[j] <= x_j <= bux[j]
                    task.putvarbound(j, bkx[j], blx[j], bux[j])
                    # Input column j of A
                    task.putacol(
                        j,  # Variable (column) index.
                        # Row index of non-zeros in column j.
                        asub[j],
                        aval[j])  # Non-zero Values of column j.
                for i in range(numcon):
                    task.putconbound(i, bkc[i], blc[i], buc[i])

                # Set up and input quadratic objective
                qsubi = [0]
                qsubj = [0]
                qval = [2.0]

                task.putqobj(qsubi, qsubj, qval)

                # Input the objective sense (minimize/maximize)
                task.putobjsense(mosek.objsense.minimize)

                # Optimize
                task.optimize()
                # Print a summary containing information
                # about the solution for debugging purposes
                # task.solutionsummary(mosek.streamtype.msg)

                prosta = task.getprosta(mosek.soltype.itr)
                solsta = task.getsolsta(mosek.soltype.itr)

                # Output a solution
                xx = [0.] * numvar
                task.getxx(mosek.soltype.itr, xx)
                '''if solsta == mosek.solsta.optimal:
                    print("Optimal solution: %s" % xx)
                elif solsta == mosek.solsta.dual_infeas_cer:
                    print("Primal or dual infeasibility.\n")
                elif solsta == mosek.solsta.prim_infeas_cer:
                    print("Primal or dual infeasibility.\n")
                elif mosek.solsta.unknown:
                    print("Unknown solution status")
                else:
                    print("Other solution status")'''

                xx = (xx[0] - omega) / dt
                if xx > temp:
                    xx = temp
                if xx < -temp:
                    xx = -temp

                if np.abs(xx / 0.12 - d_omega) < 0.02:
                    return action, False

                delta_action = xx / 0.12 - d_omega
                action[3] = action[3] + delta_action / 2
                action[4] = action[4] - delta_action / 2

                # temp = action[3] - action[4]
                '''action[3] = + xx[0]/2
                action[4] = - xx[0]/2'''
                return action, True
Exemplo n.º 13
0
def dualSDP(self,d,presolveTol=1.0e-30,split=False,outputFlag=False):
    dat, mrsp, srsp, numPnt = self.checkIfSplit()
    
    # Make mosek environment
    with mosek.Env() as env:
    
        # Create a task object and attach log stream printer
        with env.Task(0,0) as task:
            task.putdouparam(mosek.dparam.presolve_tol_x,presolveTol)
            if outputFlag: task.set_Stream(mosek.streamtype.msg, streamprinter)
    
            c = [srsp[i]/sum(srsp)+(1-srsp[i])/sum(1-srsp) for i in range(numPnt)]
            M = self.M
    
            # Bound keys for constraints
            bkc = [mosek.boundkey.lo]*(3*numPnt) + [mosek.boundkey.ra, mosek.boundkey.fx, mosek.boundkey.fx]
    
            # Bound values for constraints
            blc = [1.0]*numPnt + c + [0.0]*numPnt + [-d, 0.0, 1.0]
            buc = [+math.inf]*(3*numPnt) + [d, 0.0, 1.0]
    
            # Below is the sparse representation of the A
            # matrix stored by row. 
            asub = [[2*numPnt+i] for i in range(numPnt)] + [[numPnt+i] for i in range(numPnt)]\
            + [[i] for i in range(numPnt)] + [list(range(2*numPnt)), [], []]
            aval = [[1.0]]*(3*numPnt) + [[M]*numPnt + [1.0]*numPnt, [], []]
    
            barci   = list(range(self.numFields))
            barcj   = list(range(self.numFields))
            barcval = [1.0]*self.numFields
    
            barai   = [[self.numFields+numPnt]*self.numFields]*numPnt + [[self.numFields+numPnt]]*(2*numPnt)\
            + [[self.numFields+i for i in range(numPnt) for j in range(self.numFields)], [self.numFields+numPnt]*numPnt,
               [self.numFields+numPnt]]
            baraj   = [list(range(self.numFields))]*numPnt + [[self.numFields+i] for i in range(numPnt)]*2\
            + [[j for i in range(numPnt) for j in range(self.numFields)], [self.numFields+i for i in range(numPnt)],
               [self.numFields+numPnt]]
            baraval = [list(0.5*mrsp[i]*dat[i]) for i in range(numPnt)] + [[0.5*M]]*numPnt + [[-0.5]]*numPnt\
            + [[0.5*dat[i,j] for i in range(numPnt) for j in range(self.numFields)], [0.5]*numPnt, [1.0]]
    
            numvar = 3*numPnt
            numcon = len(bkc)
            BARVARDIM = [self.numFields+numPnt+1]
    
            # Append 'numvar' variables.
            # The variables will initially be fixed at zero (x=0). 
            task.appendvars(numvar)
    
            # Append 'numcon' empty constraints.
            # The constraints will initially have no bounds. 
            task.appendcons(numcon)
    
            # Append matrix variables of sizes in 'BARVARDIM'.
            # The variables will initially be fixed at zero. 
            task.appendbarvars(BARVARDIM)
    
            # Set the linear term c_0 in the objective.
            task.putclist([2*numPnt+i for i in range(numPnt)], [1.0]*numPnt)
            symc = task.appendsparsesymmat(BARVARDIM[0], barci, barcj, barcval)
            task.putbarcj(0, [symc], [1.0])
    
            for j in range(numvar):
                # Set the bounds on variable j
                # blx[j] <= x_j <= bux[j] 
                task.putvarbound(j, mosek.boundkey.lo, 0, +math.inf)
    
            syma = []
            for i in range(numcon):
                # Set the bounds on constraints.
                task.putconbound(i, bkc[i], blc[i], buc[i])
                # Input row i of A 
                task.putarow(i, asub[i], aval[i])
                # add coefficient matrix of PSD variables
                syma.append(task.appendsparsesymmat(BARVARDIM[0], barai[i], baraj[i], baraval[i]))
                task.putbaraij(i, 0, [syma[i]], [1.0])
    
            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.minimize)
    
            # Solve the problem and print summary
            task.optimize()
            task.solutionsummary(mosek.streamtype.msg)
    
            # Get status information about the solution
            prosta = task.getprosta(mosek.soltype.itr)
            solsta = task.getsolsta(mosek.soltype.itr)
    
            if (solsta == mosek.solsta.optimal or 
              solsta == mosek.solsta.near_optimal):
                xx = [0.]*numvar
                task.getxx(mosek.soltype.itr, xx)
                lenbarvar = BARVARDIM[0] * (BARVARDIM[0]+1) / 2
                barx = [0.]*int(lenbarvar)
                task.getbarxj(mosek.soltype.itr, 0, barx)
                barxx = [barx[(self.numFields+numPnt+1)*(i+1)-1-sum(list(range(i+1)))]\
                              for i in range(self.numFields+numPnt)]
                
                alpha = xx[:numPnt]
                beta = np.array(barxx[:self.numFields]).reshape((self.numFields,1))
                gamma = barxx[-numPnt:]
                lam = xx[numPnt:2*numPnt]
                eps = xx[-numPnt:]
                Gamma21 = np.array([[barx[self.numFields+i+(self.numFields+numPnt+1)*j-sum(list(range(j+1)))]\
                                          for j in range(self.numFields)] for i in range(numPnt)])
                time = task.getdouinf(mosek.dinfitem.optimizer_time)
                print("Optimal solution = %s\nruntime = %s seconds" % (beta.T.dot(beta)[0,0]+sum(eps),time))
                return beta, alpha, gamma, lam, eps, Gamma21
            elif (solsta == mosek.solsta.dual_infeas_cer or
                solsta == mosek.solsta.prim_infeas_cer or
                solsta == mosek.solsta.near_dual_infeas_cer or
                solsta == mosek.solsta.near_prim_infeas_cer):
                print("Primal or dual infeasibility certificate found.\n")
                return None, None, None, None, None, None
            elif solsta == mosek.solsta.unknown:
                print("Unknown solution status")
                return None, None, None, None, None, None
            else:
                print("Other solution status")
                return None, None, None, None, None, None
Exemplo n.º 14
0
def mosek_intf(A, b, G, h, c, dims, offset, solver_opts, verbose = False):
    data = {s.A : A,
            s.B : b,
            s.G : G,
            s.H : h,
            s.C : c,
            s.OFFSET : offset,
            s.DIMS : dims}

    with mosek.Env() as env:
        with env.Task(0, 0) as task:
            kwargs = sorted(solver_opts.keys())
            if "mosek_params" in kwargs:
                self._handle_mosek_params(task, solver_opts["mosek_params"])
                kwargs.remove("mosek_params")
            if kwargs:
                raise ValueError("Invalid keyword-argument '%s'" % kwargs[0])
        
            if verbose:
                # Define a stream printer to grab output from MOSEK
                def streamprinter(text):
                    import sys
                    sys.stdout.write(text)
                    sys.stdout.flush()

                env.set_Stream(mosek.streamtype.log, streamprinter)
                task.set_Stream(mosek.streamtype.log, streamprinter)
            # size of problem
            numvar = len(c) + sum(dims[s.SOC_DIM])
            numcon = len(b) + dims[s.LEQ_DIM] + sum(dims[s.SOC_DIM]) + \
                     sum([el**2 for el in dims[s.SDP_DIM]])
        
            # otherwise it crashes on empty probl.
            if numvar == 0:
                result_dict = {s.STATUS: s.OPTIMAL}
                result_dict[s.PRIMAL] = []
                result_dict[s.VALUE] = 0. + data[s.OFFSET]
                result_dict[s.EQ_DUAL] = []
                result_dict[s.INEQ_DUAL] = []
                return result_dict
        
            # objective
            task.appendvars(numvar)
            task.putclist(np.arange(len(c)), c)
            task.putvarboundlist(np.arange(numvar, dtype=int),
                                 [mosek.boundkey.fr]*numvar,
                                 np.zeros(numvar),
                                 np.zeros(numvar))
            
            # SDP variables
            if sum(dims[s.SDP_DIM]) > 0:
                task.appendbarvars(dims[s.SDP_DIM])
                
            # linear equality and linear inequality constraints
            task.appendcons(numcon)
            if A.shape[0] and G.shape[0]:
                constraints_matrix = sp.bmat([[A], [G]])
            else:
                constraints_matrix = A if A.shape[0] else G
            coefficients = np.concatenate([b, h])
                    
            row, col, el = sp.find(constraints_matrix)
            task.putaijlist(row, col, el)
        
            type_constraint = [mosek.boundkey.fx] * len(b)
            type_constraint += [mosek.boundkey.up] * dims[s.LEQ_DIM]
            sdp_total_dims = sum([cdim**2 for cdim in dims[s.SDP_DIM]])
            type_constraint += [mosek.boundkey.fx] * \
                               (sum(dims[s.SOC_DIM]) + sdp_total_dims)
        
            task.putconboundlist(np.arange(numcon, dtype=int),
                                 type_constraint,
                                 coefficients,
                                 coefficients)
        
            # cones
            current_var_index = len(c)
            current_con_index = len(b) + dims[s.LEQ_DIM]
        
            for size_cone in dims[s.SOC_DIM]:
                row, col, el = sp.find(sp.eye(size_cone))
                row += current_con_index
                col += current_var_index
                task.putaijlist(row, col, el)  # add a identity for each cone
                # add a cone constraint
                task.appendcone(mosek.conetype.quad,
                                0.0,  # unused
                                np.arange(current_var_index,
                                          current_var_index + size_cone))
                current_con_index += size_cone
                current_var_index += size_cone
                
            # SDP
            for num_sdp_var, size_matrix in enumerate(dims[s.SDP_DIM]):
                for i_sdp_matrix in range(size_matrix):
                    for j_sdp_matrix in range(size_matrix):
                        coeff = 1. if i_sdp_matrix == j_sdp_matrix else .5
                        task.putbaraij(current_con_index,
                                       num_sdp_var,
                                       [task.appendsparsesymmat(size_matrix,
                                                                [max(i_sdp_matrix,
                                                                     j_sdp_matrix)],
                                                                [min(i_sdp_matrix,
                                                                     j_sdp_matrix)],
                                                                [coeff])],
                                       [1.0])
                        current_con_index += 1
        
            # solve
            task.putobjsense(mosek.objsense.minimize)
            task.optimize()
        
            if verbose:
                task.solutionsummary(mosek.streamtype.msg)

            return format_results(task, data)
Exemplo n.º 15
0
def lp(c, G, h, A=None, b=None, taskfile=None):
    """
    Solves a pair of primal and dual LPs 

        minimize    c'*x             maximize    -h'*z - b'*y 
        subject to  G*x + s = h      subject to  G'*z + A'*y + c = 0
                    A*x = b                      z >= 0.
                    s >= 0
                    
    using MOSEK 8.0.

    (solsta, x, z, y) = lp(c, G, h, A=None, b=None).

    Input arguments 

        c is n x 1, G is m x n, h is m x 1, A is p x n, b is p x 1.  G and 
        A must be dense or sparse 'd' matrices.  c, h and b are dense 'd' 
        matrices with one column.  The default values for A and b are 
        empty matrices with zero rows.

        Optionally, the interface can write a .task file, required for
        support questions on the MOSEK solver.

    Return values

        solsta is a MOSEK solution status key.

            If solsta is mosek.solsta.optimal, then (x, y, z) contains the 
                primal-dual solution.
            If solsta is mosek.solsta.prim_infeas_cer, then (x, y, z) is a 
                certificate of primal infeasibility.
            If solsta is mosek.solsta.dual_infeas_cer, then (x, y, z) is a 
                certificate of dual infeasibility.
            If solsta is mosek.solsta.unknown, then (x, y, z) are all None.

            Other return values for solsta include:  
                mosek.solsta.dual_feas  
                mosek.solsta.near_dual_feas
                mosek.solsta.near_optimal
                mosek.solsta.near_prim_and_dual_feas
                mosek.solsta.near_prim_feas
                mosek.solsta.prim_and_dual_feas
                mosek.solsta.prim_feas
             in which case the (x,y,z) value may not be well-defined.
        
        x, y, z  the primal-dual solution.                    

    Options are passed to MOSEK solvers via the msk.options dictionary. 
    For example, the following turns off output from the MOSEK solvers
    
        >>> msk.options = {mosek.iparam.log: 0} 
    
    see the MOSEK Python API manual.                    
    """

    with mosek.Env() as env:

        if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1:
            raise TypeError("'c' must be a dense column matrix")
        n = c.size[0]
        if n < 1: raise ValueError("number of variables must be at least 1")

        if (type(G) is not matrix and type(G) is not spmatrix) or \
            G.typecode != 'd' or G.size[1] != n:
            raise TypeError("'G' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        m = G.size[0]
        if m is 0: raise ValueError("m cannot be 0")

        if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1):
            raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m)

        if A is None: A = spmatrix([], [], [], (0, n), 'd')
        if (type(A) is not matrix and type(A) is not spmatrix) or \
            A.typecode != 'd' or A.size[1] != n:
            raise TypeError("'A' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        p = A.size[0]
        if b is None: b = matrix(0.0, (0, 1))
        if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1):
            raise TypeError("'b' must be a dense matrix of size (%d,1)" % p)

        bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx]
        blc = m * [-inf] + [bi for bi in b]
        buc = list(h) + list(b)

        bkx = n * [mosek.boundkey.fr]
        blx = n * [-inf]
        bux = n * [+inf]

        colptr, asub, acof = sparse([G, A]).CCS
        aptrb, aptre = colptr[:-1], colptr[1:]

        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # set MOSEK options
            for (param, val) in options.items():
                if str(param)[:6] == "iparam":
                    task.putintparam(param, val)
                elif str(param)[:6] == "dparam":
                    task.putdouparam(param, val)
                elif str(param)[:6] == "sparam":
                    task.putstrparam(param, val)
                else:
                    raise ValueError("invalid MOSEK parameter: " + str(param))

            task.inputdata(
                m + p,  # number of constraints
                n,  # number of variables
                list(c),  # linear objective coefficients  
                0.0,  # objective fixed value  
                list(aptrb),
                list(aptre),
                list(asub),
                list(acof),
                bkc,
                blc,
                buc,
                bkx,
                blx,
                bux)

            task.putobjsense(mosek.objsense.minimize)

            if taskfile:
                task.writetask(taskfile)

            task.optimize()

            task.solutionsummary(mosek.streamtype.msg)

            solsta = task.getsolsta(mosek.soltype.bas)

            x, z = n * [0.0], m * [0.0]
            task.getsolutionslice(mosek.soltype.bas, mosek.solitem.xx, 0, n, x)
            task.getsolutionslice(mosek.soltype.bas, mosek.solitem.suc, 0, m,
                                  z)
            x, z = matrix(x), matrix(z)

            if p is not 0:
                yu, yl = p * [0.0], p * [0.0]
                task.getsolutionslice(mosek.soltype.bas, mosek.solitem.suc, m,
                                      m + p, yu)
                task.getsolutionslice(mosek.soltype.bas, mosek.solitem.slc, m,
                                      m + p, yl)
                y = matrix(yu) - matrix(yl)
            else:
                y = matrix(0.0, (0, 1))

    if (solsta is mosek.solsta.unknown):
        return (solsta, None, None, None)
    else:
        return (solsta, x, z, y)
Exemplo n.º 16
0
def main():
    # Create a MOSEK environment
    with mosek.Env() as env:
        # Create a task
        with env.Task(0, 0) as task:
            # Bound keys for constraints
            bkc = [mosek.boundkey.up,
                   mosek.boundkey.up,
                   mosek.boundkey.up]
            # Bound values for constraints
            blc = [-inf, -inf, -inf]
            buc = [100000.0, 50000.0, 60000.0]
            # Bound keys for variables
            bkx = [mosek.boundkey.lo,
                   mosek.boundkey.lo,
                   mosek.boundkey.lo]
            # Bound values for variables
            blx = [0.0, 0.0, 0.0]
            bux = [+inf, +inf, +inf]
            # Objective coefficients
            csub = [0, 1, 2]
            cval = [1.5, 2.5, 3.0]
            # We input the A matrix column-wise
            # asub contains row indexes
            asub = [0, 1, 2,
                    0, 1, 2,
                    0, 1, 2]
            # acof contains coefficients
            acof = [2.0, 3.0, 2.0,
                    4.0, 2.0, 3.0,
                    3.0, 3.0, 2.0]
            # aptrb and aptre contains the offsets into asub and acof where
            # columns start and end respectively
            aptrb = [0, 3, 6]
            aptre = [3, 6, 9]

            numvar = len(bkx)
            numcon = len(bkc)

            # Append the constraints
            task.appendcons(numcon)

            # Append the variables.
            task.appendvars(numvar)

            # Input objective
            task.putcfix(0.0)
            task.putclist(csub, cval)

            # Put constraint bounds
            task.putconboundslice(0, numcon, bkc, blc, buc)

            # Put variable bounds
            task.putvarboundslice(0, numvar, bkx, blx, bux)

            # Input A non-zeros by columns
            for j in range(numvar):
                ptrb, ptre = aptrb[j], aptre[j]
                task.putacol(j,
                             asub[ptrb:ptre],
                             acof[ptrb:ptre])

            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.maximize)

            # Optimize the task
            task.optimize()

            # Output a solution
            xx = [0.] * numvar
            task.getsolutionslice(mosek.soltype.bas,
                                  mosek.solitem.xx,
                                  0, numvar,
                                  xx)
            print("xx = {}".format(xx))

            ################# Make a change to the A matrix #############
            task.putaij(0, 0, 3.0)
            task.optimize()
            # Output a solution
            xx = [0.] * numvar
            task.getsolutionslice(mosek.soltype.bas,
                                  mosek.solitem.xx,
                                  0, numvar,
                                  xx)
            print("xx = {}".format(xx))

            ################### Add a new variable ######################
            task.appendvars(1)
            numvar+=1

            # Set bounds on new varaible
            task.putbound(mosek.accmode.var,
                          task.getnumvar() - 1,
                          mosek.boundkey.lo,
                          0,
                          +inf)

            # Change objective
            task.putcj(task.getnumvar() - 1, 1.0)

            # Put new values in the A matrix
            acolsub = [0, 2]
            acolval = [4.0, 1.0]

            task.putacol(task.getnumvar() - 1, # column index
                         acolsub,
                         acolval)
            # Change optimizer to simplex free and reoptimize
            task.putintparam(mosek.iparam.optimizer,
                             mosek.optimizertype.free_simplex)
            task.optimize()
            # Output a solution
            xx = [0.] * numvar
            task.getsolutionslice(mosek.soltype.bas,
                                  mosek.solitem.xx,
                                  0, numvar,
                                  xx)
            print("xx = {}".format(xx))

            ############# Add a new constraint #######################
            task.appendcons(1)
            numcon+=1

            # Set bounds on new constraint
            task.putconbound(task.getnumcon() - 1,
                             mosek.boundkey.up, -inf, 30000)

            # Put new values in the A matrix
            arowsub = [0, 1, 2, 3]
            arowval = [1.0, 2.0, 1.0, 1.0]

            task.putarow(task.getnumcon() - 1, # row index
                         arowsub,
                         arowval)

            task.optimize()
            # Output a solution
            xx = [0.] * numvar
            task.getsolutionslice(mosek.soltype.bas,
                                  mosek.solitem.xx,
                                  0, numvar,
                                  xx)
            print("xx = {}".format(xx))
Exemplo n.º 17
0
def socp(c, Gl=None, hl=None, Gq=None, hq=None, taskfile=None):
    """
    Solves a pair of primal and dual SOCPs

        minimize    c'*x             
        subject to  Gl*x + sl = hl      
                    Gq[k]*x + sq[k] = hq[k],  k = 0, ..., N-1
                    sl >= 0,  
                    sq[k] >= 0, k = 0, ..., N-1

        maximize    -hl'*zl - sum_k hq[k]'*zq[k] 
        subject to  Gl'*zl + sum_k Gq[k]'*zq[k] + c = 0
                    zl >= 0,  zq[k] >= 0, k = 0, ..., N-1.
                    
    using MOSEK 8.0.

    solsta, x, zl, zq = socp(c, Gl = None, hl = None, Gq = None, hq = None, taskfile=None)

    Return values

        solsta is a MOSEK solution status key.
            If solsta is mosek.solsta.optimal,
                then (x, zl, zq) contains the primal-dual solution.
            If solsta is mosek.solsta.prim_infeas_cer,
                then (x, zl, zq) is a certificate of dual infeasibility.
            If solsta is mosek.solsta.dual_infeas_cer,
                then (x, zl, zq) is a certificate of primal infeasibility.
            If solsta is mosek.solsta.unknown,
                then (x, zl, zq) are all None

            Other return values for solsta include:  
                mosek.solsta.dual_feas  
                mosek.solsta.near_dual_feas
                mosek.solsta.near_optimal
                mosek.solsta.near_prim_and_dual_feas
                mosek.solsta.near_prim_feas
                mosek.solsta.prim_and_dual_feas
                mosek.solsta.prim_feas
             in which case the (x,y,z) value may not be well-defined.
        
        x, zl, zq  the primal-dual solution.


    Options are passed to MOSEK solvers via the msk.options dictionary, 
    e.g., the following turns off output from the MOSEK solvers
    
        >>> msk.options = {mosek.iparam.log: 0} 
    
    see the MOSEK Python API manual.
    
    Optionally, the interface can write a .task file, required for
    support questions on the MOSEK solver.
    """

    with mosek.Env() as env:

        if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1:
            raise TypeError("'c' must be a dense column matrix")
        n = c.size[0]
        if n < 1: raise ValueError("number of variables must be at least 1")

        if Gl is None: Gl = spmatrix([], [], [], (0, n), tc='d')
        if (type(Gl) is not matrix and type(Gl) is not spmatrix) or \
            Gl.typecode != 'd' or Gl.size[1] != n:
            raise TypeError("'Gl' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        ml = Gl.size[0]
        if hl is None: hl = matrix(0.0, (0, 1))
        if type(hl) is not matrix or hl.typecode != 'd' or \
            hl.size != (ml,1):
            raise TypeError("'hl' must be a dense 'd' matrix of " \
                "size (%d,1)" %ml)

        if Gq is None: Gq = []
        if type(Gq) is not list or [
                G for G in Gq
                if (type(G) is not matrix and type(G) is not spmatrix)
                or G.typecode != 'd' or G.size[1] != n
        ]:
            raise TypeError("'Gq' must be a list of sparse or dense 'd' "\
                "matrices with %d columns" %n)
        mq = [G.size[0] for G in Gq]
        a = [k for k in range(len(mq)) if mq[k] == 0]
        if a: raise TypeError("the number of rows of Gq[%d] is zero" % a[0])
        if hq is None: hq = []
        if type(hq) is not list or len(hq) != len(mq) or [
                h for h in hq
                if (type(h) is not matrix and type(h) is not spmatrix)
                or h.typecode != 'd'
        ]:
            raise TypeError("'hq' must be a list of %d dense or sparse "\
                "'d' matrices" %len(mq))
        a = [k for k in range(len(mq)) if hq[k].size != (mq[k], 1)]
        if a:
            k = a[0]
            raise TypeError("'hq[%d]' has size (%d,%d).  Expected size "\
                "is (%d,1)." %(k, hq[k].size[0], hq[k].size[1], mq[k]))

        N = ml + sum(mq)
        h = matrix(0.0, (N, 1))
        if type(Gl) is matrix or [Gk for Gk in Gq if type(Gk) is matrix]:
            G = matrix(0.0, (N, n))
        else:
            G = spmatrix([], [], [], (N, n), 'd')
        h[:ml] = hl
        G[:ml, :] = Gl
        ind = ml
        for k in range(len(mq)):
            h[ind:ind + mq[k]] = hq[k]
            G[ind:ind + mq[k], :] = Gq[k]
            ind += mq[k]

        bkc = n * [mosek.boundkey.fx]
        blc = list(-c)
        buc = list(-c)

        bkx = ml * [mosek.boundkey.lo] + sum(mq) * [mosek.boundkey.fr]
        blx = ml * [0.0] + sum(mq) * [-inf]
        bux = N * [+inf]

        c = -h

        colptr, asub, acof = sparse([G.T]).CCS
        aptrb, aptre = colptr[:-1], colptr[1:]

        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # set MOSEK options
            for (param, val) in options.items():
                if str(param)[:6] == "iparam":
                    task.putintparam(param, val)
                elif str(param)[:6] == "dparam":
                    task.putdouparam(param, val)
                elif str(param)[:6] == "sparam":
                    task.putstrparam(param, val)
                else:
                    raise ValueError("invalid MOSEK parameter: " + str(param))

            task.inputdata(
                n,  # number of constraints
                N,  # number of variables
                list(c),  # linear objective coefficients  
                0.0,  # objective fixed value  
                list(aptrb),
                list(aptre),
                list(asub),
                list(acof),
                bkc,
                blc,
                buc,
                bkx,
                blx,
                bux)

            task.putobjsense(mosek.objsense.maximize)

            for k in range(len(mq)):
                task.appendcone(
                    mosek.conetype.quad, 0.0,
                    list(range(ml + sum(mq[:k]), ml + sum(mq[:k + 1]))))

            if taskfile:
                task.writetask(taskfile)

            task.optimize()

            task.solutionsummary(mosek.streamtype.msg)

            solsta = task.getsolsta(mosek.soltype.itr)

            xu, xl, zq = n * [0.0], n * [0.0], sum(mq) * [0.0]
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.slc, 0, n,
                                  xl)
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, 0, n,
                                  xu)
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, ml, N,
                                  zq)
            x = matrix(xu) - matrix(xl)

            zq = [
                matrix(zq[sum(mq[:k]):sum(mq[:k + 1])]) for k in range(len(mq))
            ]

            if ml:
                zl = ml * [0.0]
                task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, 0,
                                      ml, zl)
                zl = matrix(zl)
            else:
                zl = matrix(0.0, (0, 1))

    if (solsta is mosek.solsta.unknown):
        return (solsta, None, None, None)
    else:
        return (solsta, x, zl, zq)
Exemplo n.º 18
0
def busOpt(userGraph, busMax, time):
    ''' Using quadratic optimiaxation with integer objectives, this function returns a good estimate
    for any bus. 
    
    Params:
        userGraph   - This is the graph of the remaining students. we dont know how many exist however
        there must be at least one or it WILL return an error
        
        busMax      - Caculated beforehand, it should either be the size of the bus, or how many students could be
        put on the bus such that a feasable solution still exists. Used as a constraint on the objective
        
        time        - This is so larger sets can be calcualted in a more feasable amount of space. puts constraints
        on the solver so it does not take to long. 
    
    '''
    
    
    '''
    create a mapping for the nodes of the bus so calculations are a bit less intense each time
    '''
    #maps each to a specific num
    mapping = dict(zip(userGraph.nodes(),list(range(nx.number_of_nodes(userGraph)))))
    #reversMap is for the return value. 
    reverseMap = dict(zip(list(range(nx.number_of_nodes(userGraph))),userGraph.nodes()))
    #copies and does not modify inputs
    G = nx.relabel_nodes(userGraph,mapping, copy=True)
    
    H = np.array(nx.to_numpy_matrix(G))
    n = len(H)
    for i in range(n):
        H[i][i] = -n*2

    with mosek.Env() as env:
        # Attach a printer to the environment
        #env.set_Stream(mosek.streamtype.log, streamprinter)
        # Create a task object
        with env.Task() as task:
            # Attach a log stream printer to the task
            #task.set_Stream (mosek.streamtype.log, streamprinter)
            
            # numvar is equal to n in the nxn matrix H
            numvar = n
            '''
            For each bound, we need to define it in the array.
            each begins with mosek.boundkey.(insert postfix here)
            the endings are as follows:
                ra  -- at position i in the array if ra is the postfix, than blc[i] <= Ax[i] <= buc[i]
                fx  -- at position i in the array if fx is the postfix, than Ax[i] = blc[i]
                fr  -- at position i in the array if fr is the postfix, than -inf <= Ax[i] <= inf
                lo  -- at position i in the array if fr is the postfix, than blc[i] <= Ax[i] <= inf
                up  -- at position i in the array if fr is the postfix, than -inf <= Ax[i] <= buc[i]
            Note that we define A later. In the following case A is a 1xn matrix with lowerbound 1.0 and
            upperbound 5.0
            '''
            bkc = [mosek.boundkey.ra]
            blc = [1.0] #At least 1 kid on the bus
            buc = [busMax] #bus size
            '''
            This is where the matrix A is created, it must follow the constriants in order as provided above.
            Note in this case:
                A = [1, 1, ... , 1, 1]
            This is becase on asub each sub-array is a list, and on that list is the places below the column
            where there exists variables. Each corresponding aval is the value of that item.
            I assume this is so mosek can optimize sparce data.
            '''
            asub = [[0] for i in range(n)]
            aval = [[1.0] for i in range(n)]
            '''
            This should be a little more straigtforward. We set the constriants on the variable itself,
            saying any xi is such that 0.0 <= xi <= 1.0  for all x. When we declare it an integer func
            this ensures each xi is either 0 or 1. Not much modification should happen here unless we decide
            to do two busses at once
            '''
            bkx = [mosek.boundkey.ra] * numvar 
            blx = [0.0] * numvar
            bux = [1.0] * numvar
            
            '''
            Our objective function is as follows:
                (0.5)x.T*H*x + c.T*x
            To ensure negative semidefinate, we needed to make the diagonal of H -2*n for each entry.
            This way we could maximize the problem, however the results needed to be fixed so adding a 
            linear objective which adds the values back which otherwise would have been subtracted off.
            Making each value of c[i] == n fixed this issue.
            '''
            c = [n for i in range(n)]
            
            '''
            now we need to add the number of constraints to the problem.
            '''
            numcon = len(bkc)
            
            # Append 'numcon' empty constraints.
            # The constraints will initially have no bounds.
            task.appendcons(numcon)

            # Append 'numvar' variables.
            # The variables will initially be fixed at zero (x=0).
            task.appendvars(numvar)
        
            for j in range(numvar):
                # Set the linear term c_j in the objective.
                task.putcj(j, c[j])
                # Set the bounds on variable j
                # blx[j] <= x_j <= bux[j]
                task.putbound(mosek.accmode.var, j, bkx[j], blx[j], bux[j])
                # Input column j of A
                # Variable (column) index. # Row index of non-zeros in column j.
                task.putacol(j, asub[j], aval[j])            # Non-zero Values of column j.
            for i in range(numcon):
                task.putbound(mosek.accmode.con, i, bkc[i], blc[i], buc[i])
            
            # Set up and input quadratic objective
            qsubi = []
            qsubj = []
            qval = []
            for i in range(n):
                for j in range(0, i+1):
                    if H[i][j] != 0:
                        qsubi.append(i)
                        qsubj.append(j)
                        qval.append(H[i][j])
            #print(qsubi)
            #print(qsubj)
            #print(qval)
            task.putqobj(qsubi, qsubj, qval)
            
            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.maximize)
            # Define variables to be integers
            task.putvartypelist([i for i in range(n)],[mosek.variabletype.type_int for i in range(n)])
            
            
            # Set max solution time 
            task.putdouparam(mosek.dparam.mio_max_time, time);
            # Optimize
            task.optimize()
            # Print a summary containing information
            # about the solution for debugging purposes
            task.solutionsummary(mosek.streamtype.msg)
            
            prosta = task.getprosta(mosek.soltype.itg)
            solsta = task.getsolsta(mosek.soltype.itg)

            # Output a solution
            xx = [0.] * numvar
            task.getxx(mosek.soltype.itg, xx)
            solSet = []
#            tempSol = []
            
            '''
            This is what we will return for each bus, fixed and all
            '''
            for i in range(len(xx)):
                if xx[i] > 0.5:
                    solSet += [reverseMap[i]]
#            print(solSet)
#            print(tempSol)
            if solsta in [mosek.solsta.integer_optimal, mosek.solsta.near_integer_optimal]:
                print("Optimal solution: %s" % xx)
            elif solsta == mosek.solsta.dual_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.prim_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.near_dual_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.near_prim_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif mosek.solsta.unknown:
                if prosta == mosek.prosta.prim_infeas_or_unbounded:
                    print("Problem status Infeasible or unbounded.\n")
                elif prosta == mosek.prosta.prim_infeas:
                    print("Problem status Infeasible.\n")
                elif prosta == mosek.prosta.unkown:
                    print("Problem status unkown.\n")
                else:
                    print("Other problem status.\n")
            else:
                print("Other solution status (good)")
            v = np.array(xx)
            print(v.dot(H).dot(v)*.5 + v.dot(c))
            return solSet
Exemplo n.º 19
0
def ilp(c, G, h, A=None, b=None, I=None, taskfile=None):
    """
    Solves the mixed integer LP

        minimize    c'*x       
        subject to  G*x + s = h
                    A*x = b    
                    s >= 0
                    xi integer, forall i in I
                    
    using MOSEK 8.0.

    solsta, x = ilp(c, G, h, A=None, b=None, I=None, taskfile=None).

    Input arguments 

        G is m x n, h is m x 1, A is p x n, b is p x 1.  G and A must be 
        dense or sparse 'd' matrices.   h and b are dense 'd' matrices 
        with one column.  The default values for A and b are empty 
        matrices with zero rows.

        I is a Python set with indices of integer elements of x.  By 
        default all elements in x are constrained to be integer, i.e.,
        the default value of I is I = set(range(n))

        Dual variables are not returned for MOSEK.

        Optionally, the interface can write a .task file, required for
        support questions on the MOSEK solver.

    Return values

        solsta is a MOSEK solution status key.
            
            If solsta is mosek.solsta.integer_optimal, then x contains 
                the solution.
            If solsta is mosek.solsta.unknown, then x is None.

            Other return values for solsta include:  
                mosek.solsta.near_integer_optimal
            in which case the x value may not be well-defined,
            c.f., section 17.48 of the MOSEK Python API manual.
        
        x is the solution

    Options are passed to MOSEK solvers via the msk.options dictionary, 
    e.g., the following turns off output from the MOSEK solvers
    
    >>> msk.options = {mosek.iparam.log: 0} 
    
    see the MOSEK Python API manual.                    
    """

    with mosek.Env() as env:

        if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1:
            raise TypeError("'c' must be a dense column matrix")
        n = c.size[0]
        if n < 1: raise ValueError("number of variables must be at least 1")

        if (type(G) is not matrix and type(G) is not spmatrix) or \
            G.typecode != 'd' or G.size[1] != n:
            raise TypeError("'G' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        m = G.size[0]
        if m is 0: raise ValueError("m cannot be 0")

        if type(h) is not matrix or h.typecode != 'd' or h.size != (m, 1):
            raise TypeError("'h' must be a 'd' matrix of size (%d,1)" % m)

        if A is None: A = spmatrix([], [], [], (0, n), 'd')
        if (type(A) is not matrix and type(A) is not spmatrix) or \
            A.typecode != 'd' or A.size[1] != n:
            raise TypeError("'A' must be a dense or sparse 'd' matrix "\
                "with %d columns" %n)
        p = A.size[0]
        if b is None: b = matrix(0.0, (0, 1))
        if type(b) is not matrix or b.typecode != 'd' or b.size != (p, 1):
            raise TypeError("'b' must be a dense matrix of size (%d,1)" % p)

        if I is None: I = set(range(n))

        if type(I) is not set:
            raise TypeError("invalid argument for integer index set")

        for i in I:
            if type(i) is not int:
                raise TypeError("invalid integer index set I")

        if len(I) > 0 and min(I) < 0:
            raise IndexError("negative element in integer index set I")
        if len(I) > 0 and max(I) > n - 1:
            raise IndexError(
                "maximum element in in integer index set I is larger than n-1")

        bkc = m * [mosek.boundkey.up] + p * [mosek.boundkey.fx]
        blc = m * [-inf] + [bi for bi in b]
        buc = list(h) + list(b)

        bkx = n * [mosek.boundkey.fr]
        blx = n * [-inf]
        bux = n * [+inf]

        colptr, asub, acof = sparse([G, A]).CCS
        aptrb, aptre = colptr[:-1], colptr[1:]

        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # set MOSEK options
            for (param, val) in options.items():
                if str(param)[:6] == "iparam":
                    task.putintparam(param, val)
                elif str(param)[:6] == "dparam":
                    task.putdouparam(param, val)
                elif str(param)[:6] == "sparam":
                    task.putstrparam(param, val)
                else:
                    raise ValueError("invalid MOSEK parameter: " + str(param))

            task.inputdata(
                m + p,  # number of constraints
                n,  # number of variables
                list(c),  # linear objective coefficients  
                0.0,  # objective fixed value  
                list(aptrb),
                list(aptre),
                list(asub),
                list(acof),
                bkc,
                blc,
                buc,
                bkx,
                blx,
                bux)

            task.putobjsense(mosek.objsense.minimize)

            # Define integer variables
            if len(I) > 0:
                task.putvartypelist(list(I),
                                    len(I) * [mosek.variabletype.type_int])

            task.putintparam(mosek.iparam.mio_mode, mosek.miomode.satisfied)

            if taskfile:
                task.writetask(taskfile)

            task.optimize()

            task.solutionsummary(mosek.streamtype.msg)

            if len(I) > 0:
                solsta = task.getsolsta(mosek.soltype.itg)
            else:
                solsta = task.getsolsta(mosek.soltype.bas)

            x = n * [0.0]
            if len(I) > 0:
                task.getsolutionslice(mosek.soltype.itg, mosek.solitem.xx, 0,
                                      n, x)
            else:
                task.getsolutionslice(mosek.soltype.bas, mosek.solitem.xx, 0,
                                      n, x)
            x = matrix(x)

    if (solsta is mosek.solsta.unknown):
        return (solsta, None)
    else:
        return (solsta, x)
Exemplo n.º 20
0
def main():
    # Make a MOSEK environment
    with mosek.Env() as env:
        # Attach a printer to the environment
        env.set_Stream(mosek.streamtype.log, streamprinter)

        # Create a task
        with env.Task(0, 0) as task:
            # Attach a printer to the task
            task.set_Stream(mosek.streamtype.log, streamprinter)

            bkc = [mosek.boundkey.fx]
            blc = [1.0]
            buc = [1.0]

            c = [0.0, 0.0, 0.0,
                 1.0, 1.0, 1.0]
            bkx = [mosek.boundkey.lo, mosek.boundkey.lo, mosek.boundkey.lo,
                   mosek.boundkey.fr, mosek.boundkey.fr, mosek.boundkey.fr]
            blx = [0.0, 0.0, 0.0,
                   -inf, -inf, -inf]
            bux = [inf, inf, inf,
                   inf, inf, inf]

            asub = [[0], [0], [0]]
            aval = [[1.0], [1.0], [2.0]]

            numvar = len(bkx)
            numcon = len(bkc)
            NUMANZ = 4

            # Append 'numcon' empty constraints.
            # The constraints will initially have no bounds.
            task.appendcons(numcon)

            #Append 'numvar' variables.
            # The variables will initially be fixed at zero (x=0).
            task.appendvars(numvar)

            for j in range(numvar):
              # Set the linear term c_j in the objective.
                task.putcj(j, c[j])
              # Set the bounds on variable j
              # blx[j] <= x_j <= bux[j]
                task.putvarbound(j, bkx[j], blx[j], bux[j])

            for j in range(len(aval)):
              # Input column j of A
                task.putacol(j,                  # Variable (column) index.
                             # Row index of non-zeros in column j.
                             asub[j],
                             aval[j])            # Non-zero Values of column j.
            for i in range(numcon):
                task.putconbound(i, bkc[i], blc[i], buc[i])

                # Input the cones
            task.appendcone(mosek.conetype.quad,
                            0.0,
                            [3, 0, 1])
            task.appendcone(mosek.conetype.rquad,
                            0.0,
                            [4, 5, 2])

            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.minimize)

            # Optimize the task
            task.optimize()
            # Print a summary containing information
            # about the solution for debugging purposes
            task.solutionsummary(mosek.streamtype.msg)
            prosta = task.getprosta(mosek.soltype.itr)
            solsta = task.getsolsta(mosek.soltype.itr)

            # Output a solution
            xx = [0.] * numvar
            task.getxx(mosek.soltype.itr,
                       xx)

            if solsta == mosek.solsta.optimal:
                print("Optimal solution: %s" % xx)
            elif solsta == mosek.solsta.dual_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif solsta == mosek.solsta.prim_infeas_cer:
                print("Primal or dual infeasibility.\n")
            elif mosek.solsta.unknown:
                print("Unknown solution status")
            else:
                print("Other solution status")
Exemplo n.º 21
0
def solve(form, display=True, export=False):

    numlc, numvar = form.linear.shape
    if isinstance(form, SOCProg):
        qmat = form.qmat
    else:
        qmat = []

    ind_int = np.where(form.vtype == 'I')[0]
    ind_bin = np.where(form.vtype == 'B')[0]

    if ind_bin.size:
        form.ub[ind_bin] = 1
        form.lb[ind_bin] = 0

    ind_ub = np.where((form.ub != np.inf) & (form.lb == -np.inf))[0]
    ind_lb = np.where((form.lb != -np.inf) & (form.ub == np.inf))[0]
    ind_ra = np.where((form.lb != -np.inf) & (form.ub != np.inf))[0]
    ind_fr = np.where((form.lb == -np.inf) & (form.ub == np.inf))[0]
    ind_eq = np.where(form.sense)[0]
    ind_ineq = np.where(form.sense == 0)[0]

    with mosek.Env() as env:

        with env.Task(0, 0) as task:

            task.appendvars(numvar)
            task.appendcons(numlc)

            if ind_ub.size:
                task.putvarboundlist(ind_ub, [mosek.boundkey.up] * len(ind_ub),
                                     form.lb[ind_ub], form.ub[ind_ub])

            if ind_lb.size:
                task.putvarboundlist(ind_lb, [mosek.boundkey.lo] * len(ind_lb),
                                     form.lb[ind_lb], form.ub[ind_lb])

            if ind_ra.size:
                task.putvarboundlist(ind_ra, [mosek.boundkey.ra] * len(ind_ra),
                                     form.lb[ind_ra], form.ub[ind_ra])

            if ind_fr.size:
                task.putvarboundlist(ind_fr, [mosek.boundkey.fr] * len(ind_fr),
                                     form.lb[ind_fr], form.ub[ind_fr])

            if ind_int.size:
                task.putvartypelist(ind_int, [mosek.variabletype.type_int] *
                                    len(ind_int))

            if ind_bin.size:
                task.putvartypelist(ind_bin, [mosek.variabletype.type_int] *
                                    len(ind_bin))

            task.putcslice(0, numvar, form.obj.flatten())
            task.putobjsense(mosek.objsense.minimize)

            coo = coo_matrix(form.linear)
            task.putaijlist(coo.row, coo.col, coo.data)

            if ind_eq.size:
                task.putconboundlist(ind_eq, [mosek.boundkey.fx] * len(ind_eq),
                                     form.const[ind_eq], form.const[ind_eq])
            if ind_ineq.size:
                task.putconboundlist(ind_ineq,
                                     [mosek.boundkey.up] * len(ind_ineq),
                                     [-np.inf] * len(ind_ineq),
                                     form.const[ind_ineq])

            for cone in qmat:
                task.appendcone(mosek.conetype.quad, 0.0, cone)

            if display:
                print('Being solved by Mosek...')

            t0 = time.process_time()
            task.optimize()
            stime = time.process_time() - t0

            soltype = mosek.soltype
            solsta = None
            for stype in [soltype.bas, soltype.itr, soltype.itg]:
                try:
                    solsta = task.getsolsta(stype)
                    if display:
                        print('Solution status: {0}'.format(solsta.__repr__()))
                        print('Running time: {0:0.4f}s'.format(stime))

                    break
                except:
                    pass

            xx = [0.] * numvar
            task.getxx(stype, xx)

            if export:
                task.writedata("out.mps")

            if solsta in [mosek.solsta.optimal, mosek.solsta.integer_optimal]:
                solution = Solution(xx[0], xx, solsta)
            else:
                warnings.warn('No feasible solution can be found.')
                solution = None

            return solution
Exemplo n.º 22
0
def ALIGNF(km_list, ky, centering=True):
    """
    Parameters:
    -----------
    km_list, a list of kernel matrices, list of 2d array 
    ky, target kernel,  2d array

    Returns:
    --------
    xx, the weight for each kernels
    """
    n_feat = len(km_list)
    km_list_copy = []

    # center the kernel first
    for i in range(n_feat):
        if centering:
            km_list_copy.append(center(km_list[i].copy()))
        else:
            km_list_copy.append(km_list[i].copy())
    if centering:
        ky_copy = center(ky.copy())
    else:
        ky_copy = ky.copy()

    a = np.zeros(n_feat)
    for i in range(n_feat):
        a[i] = f_dot(km_list_copy[i], ky_copy)

    M = np.zeros((n_feat, n_feat))
    for i in range(n_feat):
        for j in range(i,n_feat):
            M[i,j] = f_dot(km_list_copy[i],km_list_copy[j])
            M[j,i] = M[i,j]

    Q = 2*M
    C = -2*a

    Q = Q + np.diag(np.ones(n_feat)*1e-10)

    ################################################
    # Using mosek to solve the quadratice programming

    # Set upper diagonal element to zeros, mosek only accept lower triangle
    iu = np.triu_indices(n_feat,1)
    Q[iu] = 0

    # start solving with mosek
    inf = 0.0
    env = mosek.Env()
    env.set_Stream(mosek.streamtype.log, streamprinter)

    # Create a task                                                     
    task = env.Task()
    task.set_Stream(mosek.streamtype.log, streamprinter)

    # Set up bound for variables                                  
    bkx = [mosek.boundkey.lo]* n_feat
    blx = [0.0] * n_feat
    bux = [+inf]* n_feat

    numvar = len(bkx)

    task.appendvars(numvar)

    for j in range(numvar):
        task.putcj(j,C[j])
        task.putvarbound(j,bkx[j],blx[j],bux[j])

    # Set up quadratic objective                                         
    inds = np.nonzero(Q)
    qsubi = inds[0].tolist()
    qsubj = inds[1].tolist()
    qval = Q[inds].tolist()

    # Input quadratic objective                                         
    task.putqobj(qsubi,qsubj,qval)

    # Input objective sense (minimize/mximize)                          
    task.putobjsense(mosek.objsense.minimize)

    task.optimize()

    # Print a summary containing information                            
    # about the solution for debugging purposes                         
    task.solutionsummary(mosek.streamtype.msg)

    solsta = task.getsolsta(mosek.soltype.itr)
    if (solsta == mosek.solsta.optimal or
        solsta == mosek.solsta.near_optimal):
        # Output a solution                                              
        xx = np.zeros(numvar, float)
        task.getxx(mosek.soltype.itr, xx)
        #xx = xx/np.linalg.norm(xx)
        return xx
    else:
        print "Solution not optimal or near optimal"
        print solsta
        return None
Exemplo n.º 23
0
def main():
    # Make a MOSEK environment
    env = mosek.Env()
    # Attach a printer to the environment
    env.set_Stream(mosek.streamtype.log, streamprinter)

    # Create a task
    task = env.Task(0, 0)
    # Attach a printer to the task
    task.set_Stream(mosek.streamtype.log, streamprinter)

    bkc = [mosek.boundkey.up, mosek.boundkey.lo]
    blc = [-inf, -4.0]
    buc = [250.0, inf]

    bkx = [mosek.boundkey.lo, mosek.boundkey.lo]
    blx = [0.0, 0.0]
    bux = [inf, inf]

    c = [1.0, 0.64]

    asub = [array([0, 1]), array([0, 1])]
    aval = [array([50.0, 3.0]), array([31.0, -2.0])]

    numvar = len(bkx)
    numcon = len(bkc)

    # Append 'numcon' empty constraints.
    # The constraints will initially have no bounds.
    task.appendcons(numcon)

    #Append 'numvar' variables.
    # The variables will initially be fixed at zero (x=0).
    task.appendvars(numvar)

    for j in range(numvar):
        # Set the linear term c_j in the objective.
        task.putcj(j, c[j])
        # Set the bounds on variable j
        # blx[j] <= x_j <= bux[j]
        task.putvarbound(j, bkx[j], blx[j], bux[j])
        # Input column j of A
        task.putacol(
            j,  # Variable (column) index.
            asub[j],  # Row index of non-zeros in column j.
            aval[j])  # Non-zero Values of column j.

    task.putconboundlist(range(numcon), bkc, blc, buc)

    # Input the objective sense (minimize/maximize)
    task.putobjsense(mosek.objsense.maximize)

    # Define variables to be integers
    task.putvartypelist(
        [0, 1], [mosek.variabletype.type_int, mosek.variabletype.type_int])

    # Optimize the task
    task.optimize()

    # Print a summary containing information
    # about the solution for debugging purposes
    task.solutionsummary(mosek.streamtype.msg)

    prosta = task.getprosta(mosek.soltype.itg)
    solsta = task.getsolsta(mosek.soltype.itg)

    # X

    # Output a solution
    xx = zeros(numvar, float)
    task.getxx(mosek.soltype.itg, xx)

    if solsta in [
            mosek.solsta.integer_optimal, mosek.solsta.near_integer_optimal
    ]:
        print("Optimal solution: %s" % xx)
    elif solsta == mosek.solsta.dual_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.prim_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.near_dual_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif solsta == mosek.solsta.near_prim_infeas_cer:
        print("Primal or dual infeasibility.\n")
    elif mosek.solsta.unknown:
        if prosta == mosek.prosta.prim_infeas_or_unbounded:
            print("Problem status Infeasible or unbounded.\n")
        elif prosta == mosek.prosta.prim_infeas:
            print("Problem status Infeasible.\n")
        elif prosta == mosek.prosta.unkown:
            print("Problem status unkown.\n")
        else:
            print("Other problem status.\n")
    else:
        print("Other solution status")
 def main():
 # Open MOSEK and create an environment and task
 # Make a MOSEK environment
     with mosek.Env() as env:
         # Attach a printer to the environment
         env.set_Stream(mosek.streamtype.log, streamprinter)
         # Create a task
         with env.Task() as task:
             task.set_Stream(mosek.streamtype.log, streamprinter)
             
             # Bound keys for variables
             numvar = numvars
             bkx = [mosek.boundkey.ra] * numvar
 #            bkx = [mosek.boundkey.fr] * numvar
             
             # Bound values for variables
             temppricelow = initial*0.9
             temppricehigh = initial*1.1
             blx = []
             bux = []
 #            blx = [inf] * numvar
 #            bux = [inf] * numvar
             for i in range(numvar):
                 blx.append(temppricelow[i])
                 bux.append(temppricehigh[i])
             
             # Objective linear coefficients
             c = linearpart
             
             # Append 'numcon' empty constraints.
             # The constraints will initially have no bounds.
             task.appendcons(0)
         
             # Append 'numvar' variables.
             # The variables will initially be fixed at zero (x=0).
             task.appendvars(numvar)
 
             for j in range(numvar):
                 # Set the linear term c_j in the objective.
                 task.putcj(j, c[j])
                 
                 # Set the bounds on variable j
                 # blx[j] <= x_j <= bux[j] 
                 task.putvarbound(j, bkx[j], blx[j], bux[j]) 
 
             # Set up and input quadratic objective
             qsubi = []
             for i in range(numvar):
                 qsubi.append(i)
             qsubj = qsubi
             qval = 2*quadpart
 
             task.putqobj(qsubi, qsubj, qval)
 
             # Input the objective sense (minimize/maximize)
             task.putobjsense(mosek.objsense.maximize)
 
             # Optimize
             task.optimize()
             
             # Print a summary containing information
             # about the solution for debugging purposes
 #                task.solutionsummary(mosek.streamtype.msg)
 
             # Output a solution
             xx = [0.] * numvar
             task.getxx(mosek.soltype.itr,
                        xx)
 
             return xx
Exemplo n.º 25
0
def mosek_solve():
    # LOAD VARIABLES
    n_utxo = len(tx.utxo_set)
    n_out  = len(tx.outputs)
    U      = tx.utxo_set
    O      = tx.outputs
    Vu     = [int(U[j]['value']) for j in range(n_utxo)]
    Vo     = [int(O[j]['value']) for j in range(n_out)]
    Su     = [int(U[j]['size'])  for j in range(n_utxo)]
    So     = [int(O[j]['size'])  for j in range(n_out)]

    Ms     = int(tx.params['max_size'])
    alpha  = float(tx.params['fee_rate'])
    T      = int(tx.params['dust_threshold'])
    eps    = int(tx.params['min_change_output'])
    beta   = int(tx.params['change_output_size'])

    # Sum of input values
    sum_Vu = sum(Vu[j] for j in range(n_utxo))
    # Sum of output values
    sum_Vo = sum(Vo[j] for j in range(n_out))
    # Sum of output size
    sum_So = sum(So[j] for j in range(n_out))
    # Maximum change value = sum_Vu - sum_Vo
    Mc = sum_Vu - sum_Vo
    # Minimum utxo
    # Mc = min(Vu)

    # SOLVE
    # Make mosek environment
    with mosek.Env() as env:
        # Create a task object
        with env.Task(0, 0) as task:
            # Attach a log stream printer to the task
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # Bound keys for constraints
            bkc = [
                mosek.boundkey.ra,
                mosek.boundkey.fx,
                mosek.boundkey.up
            ]

            # Bound values for constraints
            blc = [0.0,         sum_Vo + alpha * sum_So, -inf]
            buc = [Ms - sum_So, sum_Vo + alpha * sum_So, eps]


            # Bound keys for variables
            bkx = [mosek.boundkey.ra for j in range(n_utxo)] # l <= x <= u
            bkx.append(mosek.boundkey.ra)
            bkx.append(mosek.boundkey.ra)


            # Bound values for variables
            blx = [0.0 for j in range(n_utxo)] # x_i
            blx.append(0.0)                    # t
            blx.append(0.0)                    # z_v
            bux = [1.0 for j in range(n_utxo)]
            bux.append(1.0)
            bux.append(Mc)

            # Objective coefficients
            c = [Su[j] for j in range(n_utxo)]
            c.append(beta)
            c.append(0.0)

            # Below is the sparse representation of the A
            # matrix stored by column.
            asub = [
                [0, 1] for j in range(n_utxo)
            ]
            asub.append([0, 1, 2])
            asub.append([1, 2])

            aval = [
                [Su[j], Vu[j] - alpha * Su[j]] for j in range(n_utxo)
            ]
            aval.append([beta, -alpha * beta, -Mc])
            aval.append([-1.0, 1.0])


            # numcon and numvar
            numcon = len(bkc)
            numvar = len(bkx)

            assert numvar == n_utxo + 2
            assert numcon == 3

            # Append 'numcon' empty constraints.
            # The constraints will initially have no bounds.
            task.appendcons(numcon)
            # Append 'numvar' variables.
            # The variables will initially be fixed at zero (x=0).
            task.appendvars(numvar)

            for j in range(numvar):
                # Set the linear term c_j in the objective.
                task.putcj(j, c[j])

                # Set the bounds on variable j
                # blx[j] <= x_j <= bux[j]
                task.putvarbound(j, bkx[j], blx[j], bux[j])

                # Input column j of A
                task.putacol(
                    j,       # Variable (column) index.
                    asub[j], # Row index of non-zeros in column j.
                    aval[j]  # Non-zero Values of column j.
                )


            task.putconboundlist(range(numcon), bkc, blc, buc)

            # Input the objective sense (minimize/maximize)
            task.putobjsense(mosek.objsense.minimize)

            # Define variables to be integers
            task.putvartypelist(
                [j for j in range(n_utxo + 1)],
                [mosek.variabletype.type_int for j in range(n_utxo + 1)]
            )

            # Set max solution time
            task.putdouparam(mosek.dparam.mio_max_time, 200.0);

            # Solve the problem
            task.optimize()

            # Print a summary containing information
            # about the solution for debugging purposes
            task.solutionsummary(mosek.streamtype.msg)
            prosta = task.getprosta(mosek.soltype.itg)
            solsta = task.getsolsta(mosek.soltype.itg)

            # Output a solution
            xx = [0.] * numvar
            task.getxx(mosek.soltype.itg, xx)

            if solsta in [mosek.solsta.integer_optimal]:
                print("Optimal solution: %s" % xx)
                return xx
            elif solsta == mosek.solsta.prim_feas:
                print("Feasible solution: %s" % xx)
            elif mosek.solsta.unknown:
                if prosta == mosek.prosta.prim_infeas_or_unbounded:
                    print("Problem status Infeasible or unbounded.\n")
                elif prosta == mosek.prosta.prim_infeas:
                    print("Problem status Infeasible.\n")
                elif prosta == mosek.prosta.unkown:
                    print("Problem status unkown.\n")
                else:
                    print("Other problem status.\n")
            else:
                print("Other solution status")
Exemplo n.º 26
0
    def run(self, *args, **kwargs):
        import mosek
        import random

        # define
        CPU = 0
        MEM = 1
        DISK = 2
        TS = 3  # amount of PRI + STD
        PRI = 4
        STD = 5
        WEIGHT = 6
        inf = 0.0

        # TEMPLATE_DEFINE = [CPU, MEM, DISK, TS, PRI, STD, WEIGHT]
        templates_id, templates, server_id, servers = [], [], [], []
        re = []

        for server_info in kwargs["servers"]:
            if server_info[1][0] > 0 and server_info[1][1] > 0 and server_info[
                    1][2] > 0:
                server_id.append(server_info[0])
                servers.append(server_info[1])

        for template_info in kwargs["templates"]:
            if template_info[1][0] > 0 and template_info[1][
                    1] > 0 and template_info[1][2] > 0:
                templates_id.append(template_info[0])
                templates.append(template_info[1])

        if not templates_id or not server_id:
            for i in range(len(templates_id)):
                re.append(dict(id=templates_id[i], plan=[]))
            return ErrorCode.success, re
        # templates_id, templates = [x[0] for x in kwargs["templates"]], [x[1] for x in kwargs["templates"]]
        # server_id, servers = [x[0] for x in kwargs["servers"]], [x[1] for x in kwargs["servers"]]

        numserver = len(servers)
        numtemplate = len(templates)

        # c = [x[WEIGHT] for x in templates] * numserver
        c = [x[WEIGHT] * (x[CPU] + x[MEM] + x[DISK])
             for x in templates] * numserver

        # 注意浅拷贝
        clause = [
            numtemplate * numserver * [0]
            for _ in range(3 * numserver + numserver * numtemplate)
        ]

        # set constraints functions
        for i in range(numserver):
            j = i
            clause[j][i * numtemplate:(i * numtemplate + numtemplate)] = [
                t[CPU] for t in templates
            ]

            j += numserver
            clause[j][i * numtemplate:(i * numtemplate + numtemplate)] = [
                t[MEM] for t in templates
            ]

            j += numserver
            clause[j][i * numtemplate:(i * numtemplate + numtemplate)] = [
                t[DISK] for t in templates
            ]

            j += numserver
            for k in range(numtemplate):
                for s in range(numserver):
                    clause[j][s * numtemplate +
                              k] = (1 - templates[k][TS]) if s == i else 1
                j += numserver

        # Bound keys for constraints 3 * count(server) + count(template) * count(server) = (3 + 4) * 5
        bkc = 3 * numserver * [mosek.boundkey.ra] + numserver * numtemplate * [
            mosek.boundkey.lo
        ]
        blc = (3 * numserver + numtemplate * numserver) * [0]
        buc = [x[CPU] for x in servers] + [x[MEM] for x in servers] + [x[DISK] for x in servers] \
              + numserver * numtemplate * [+inf]

        bkx = numserver * numtemplate * [mosek.boundkey.lo]
        blx = numserver * numtemplate * [0]
        bux = numserver * numtemplate * [+inf]

        # 条件做矩阵转置
        clause_T = [[r[col] for r in clause] for col in range(len(clause[0]))]
        asub = [[i for i in range(len(col)) if col[i]] for col in clause_T]
        aval = [[i for i in col if i] for col in clause_T]

        numvar = len(bkx)
        numcon = len(bkc)

        with mosek.Env() as env:
            with env.Task(0, 0) as task:
                task.appendcons(numcon)
                task.appendvars(numvar)

                for j in range(numvar):
                    task.putcj(j, c[j])
                    task.putvarbound(j, bkx[j], blx[j], bux[j])
                    task.putacol(j, asub[j], aval[j])

                task.putconboundlist(range(numcon), bkc, blc, buc)
                task.putobjsense(mosek.objsense.maximize)
                task.putvartypelist([x for x in range(len(c))],
                                    len(c) * [mosek.variabletype.type_int])
                task.putdouparam(mosek.dparam.mio_max_time, 60.0)
                task.optimize()
                task.solutionsummary(mosek.streamtype.msg)
                prosta = task.getprosta(mosek.soltype.itg)
                solsta = task.getsolsta(mosek.soltype.itg)
                xx = [0.] * numvar
                task.getxx(mosek.soltype.itg, xx)
                # print(xx)
                xx = [int(x) for x in xx]
                result = [
                    xx[i:i + numtemplate]
                    for i in range(0, len(xx), numtemplate)
                ]
                result = [(server_id[r], result[r])
                          for r in range(len(result))]

                for i in range(len(templates_id)):
                    flag = []
                    re_by_template = [x[1][i] for x in result]
                    # if plan exists
                    init_re = [[] for _ in range((sum(re_by_template) //
                                                  templates[i][TS]))]
                    if init_re:
                        for r in range(len(init_re)):
                            for _ in re_by_template:
                                if max(re_by_template) == 0:
                                    init_re[r].append(-1)
                                else:
                                    idx = re_by_template.index(
                                        max(re_by_template))
                                    if idx in flag:
                                        for xx in range(len(re_by_template)):
                                            if xx in flag:
                                                continue
                                            else:
                                                if re_by_template[xx] == 0:
                                                    continue
                                                else:
                                                    idx = xx
                                                    break
                                    init_re[r].append(server_id[idx])
                                    re_by_template[idx] -= 1
                                    flag.append(idx)
                                if len(init_re[r]) == templates[i][TS]:
                                    flag = []
                                    random.shuffle(init_re[r])
                                    random.shuffle(init_re[r])
                                    break
                    re.append(dict(id=templates_id[i], plan=init_re))

                return ErrorCode.success, re
Exemplo n.º 27
0
import pyutilib.th as unittest

from pyomo.opt import (TerminationCondition, SolutionStatus, SolverStatus)
import pyomo.environ as pyo
import pyomo.kernel as pmo
import sys

try:
    import mosek
    mosek_available = True
    mosek_version = mosek.Env().getversion()
except ImportError:
    mosek_available = False
    modek_version = None

diff_tol = 1e-3


@unittest.skipIf(not mosek_available, "MOSEK's python bindings are missing.")
class MOSEKPersistentTests(unittest.TestCase):
    def setUp(self):
        self.stderr = sys.stderr
        sys.stderr = None

    def tearDown(self):
        sys.stderr = self.stderr

    def test_interface_call(self):

        interface_instance = type(pyo.SolverFactory('mosek_persistent'))
        alt_1 = pyo.SolverFactory('mosek', solver_io='persistent')
Exemplo n.º 28
0
def conelp(c, G, h, dims=None, taskfile=None):
    """
    Solves a pair of primal and dual SOCPs

        minimize    c'*x
        subject to  G*x + s = h
                    s >= 0

        maximize    -h'*z 
        subject to  G'*z + c = 0
                    z >= 0 

    using MOSEK 8.0.   

    The inequalities are with respect to a cone C defined as the Cartesian
    product of N + M + 1 cones:
    
        C = C_0 x C_1 x .... x C_N x C_{N+1} x ... x C_{N+M}.

    The first cone C_0 is the nonnegative orthant of dimension ml.
    The next N cones are second order cones of dimension mq[0], ..., 
    mq[N-1].  The second order cone of dimension m is defined as
    
        { (u0, u1) in R x R^{m-1} | u0 >= ||u1||_2 }.

    The next M cones are positive semidefinite cones of order ms[0], ...,
    ms[M-1] >= 0.  
       
    The formats of G and h are identical to that used in solvers.conelp().


    Input arguments.

        c is a dense 'd' matrix of size (n,1).

        dims is a dictionary with the dimensions of the components of C.  
        It has three fields.
        - dims['l'] = ml, the dimension of the nonnegative orthant C_0.
          (ml >= 0.)
        - dims['q'] = mq = [ mq[0], mq[1], ..., mq[N-1] ], a list of N 
          integers with the dimensions of the second order cones C_1, ..., 
          C_N.  (N >= 0 and mq[k] >= 1.)
        - dims['s'] = ms = [ ms[0], ms[1], ..., ms[M-1] ], a list of M  
          integers with the orders of the semidefinite cones C_{N+1}, ...,
          C_{N+M}.  (M >= 0 and ms[k] >= 0.)
        The default value of dims is {'l': G.size[0], 'q': [], 's': []}.

        G is a dense or sparse 'd' matrix of size (K,n), where

            K = ml + mq[0] + ... + mq[N-1] + ms[0]**2 + ... + ms[M-1]**2.

        Each column of G describes a vector 

            v = ( v_0, v_1, ..., v_N, vec(v_{N+1}), ..., vec(v_{N+M}) ) 

        in V = R^ml x R^mq[0] x ... x R^mq[N-1] x S^ms[0] x ... x S^ms[M-1]
        stored as a column vector

            [ v_0; v_1; ...; v_N; vec(v_{N+1}); ...; vec(v_{N+M}) ].

        Here, if u is a symmetric matrix of order m, then vec(u) is the 
        matrix u stored in column major order as a vector of length m**2.
        We use BLAS unpacked 'L' storage, i.e., the entries in vec(u) 
        corresponding to the strictly upper triangular entries of u are 
        not referenced.

        h is a dense 'd' matrix of size (K,1), representing a vector in V,
        in the same format as the columns of G.
    
        A is a dense or sparse 'd' matrix of size (p,n).  The default value
        is a sparse 'd' matrix of size (0,n).

        b is a dense 'd' matrix of size (p,1).   The default value is a 
        dense 'd' matrix of size (0,1).
     
        Optionally, the interface can write a .task file, required for
        support questions on the MOSEK solver.
 
    Return values

        solsta is a MOSEK solution status key.

            If solsta is mosek.solsta.optimal,
                then (x, zl, zq, zs) contains the primal-dual solution.
            If solsta is moseksolsta.prim_infeas_cer,
                then (x, zl, zq, zs) is a certificate of dual infeasibility.
            If solsta is moseksolsta.dual_infeas_cer,
                then (x, zl, zq, zs) is a certificate of primal infeasibility.
            If solsta is mosek.solsta.unknown,
                then (x, zl, zq, zs) are all None

            Other return values for solsta include:  
                mosek.solsta.dual_feas  
                mosek.solsta.near_dual_feas
                mosek.solsta.near_optimal
                mosek.solsta.near_prim_and_dual_feas
                mosek.solsta.near_prim_feas
                mosek.solsta.prim_and_dual_feas
                mosek.solsta.prim_feas
            in which case the (x,y,z) value may not be well-defined.
        
        x, z the primal-dual solution.


    Options are passed to MOSEK solvers via the msk.options dictionary, 
    e.g., the following turns off output from the MOSEK solvers
    
        >>> msk.options = {mosek.iparam.log:0} 
    
    see the MOSEK Python API manual.                    
    """

    with mosek.Env() as env:

        if dims is None:
            (solsta, x, y, z) = lp(c, G, h)
            return (solsta, x, z, None)

        N, n = G.size

        ml, mq, ms = dims['l'], dims['q'], [k * k for k in dims['s']]
        cdim = ml + sum(mq) + sum(ms)
        if cdim is 0: raise ValueError("ml+mq+ms cannot be 0")

        # Data for kth 'q' constraint are found in rows indq[k]:indq[k+1] of G.
        indq = [dims['l']]
        for k in dims['q']:
            indq = indq + [indq[-1] + k]

        # Data for the kth 's' constraint are found in rows indq[-1] + (inds[k]:inds[k+1]) of G.
        inds = [0]
        for k in dims['s']:
            inds = inds + [inds[-1] + k * k]

        if type(h) is not matrix or h.typecode != 'd' or h.size[1] != 1:
            raise TypeError("'h' must be a 'd' matrix with 1 column")
        if type(G) is matrix or type(G) is spmatrix:
            if G.typecode != 'd' or G.size[0] != cdim:
                raise TypeError("'G' must be a 'd' matrix with %d rows " %
                                cdim)
            if h.size[0] != cdim:
                raise TypeError("'h' must have %d rows" % cdim)
        else:
            raise TypeError("'G' must be a matrix")

        if len(dims['q']) and min(dims['q']) < 1:
            raise TypeError("dimensions of quadratic cones must be positive")

        if len(dims['s']) and min(dims['s']) < 1:
            raise TypeError(
                "dimensions of semidefinite cones must be positive")

        bkc = n * [mosek.boundkey.fx]
        blc = list(-c)
        buc = list(-c)

        dimx = ml + sum(mq)
        bkx = ml * [mosek.boundkey.lo] + sum(mq) * [mosek.boundkey.fr]
        blx = ml * [0.0] + sum(mq) * [-inf]
        bux = dimx * [+inf]
        c = list(-h)

        cl, cs = c[:dimx], sparse(c[dimx:])
        Gl, Gs = sparse(G[:dimx, :]), sparse(G[dimx:, :])
        colptr, asub, acof = Gl.T.CCS
        aptrb, aptre = colptr[:-1], colptr[1:]

        with env.Task(0, 0) as task:
            task.set_Stream(mosek.streamtype.log, streamprinter)

            # set MOSEK options
            for (param, val) in options.items():
                if str(param)[:6] == "iparam":
                    task.putintparam(param, val)
                elif str(param)[:6] == "dparam":
                    task.putdouparam(param, val)
                elif str(param)[:6] == "sparam":
                    task.putstrparam(param, val)
                else:
                    raise ValueError("invalid MOSEK parameter: " + str(param))

            task.inputdata(
                n,  # number of constraints
                dimx,  # number of variables
                cl,  # linear objective coefficients  
                0.0,  # objective fixed value  
                list(aptrb),
                list(aptre),
                list(asub),
                list(acof),
                bkc,
                blc,
                buc,
                bkx,
                blx,
                bux)

            task.putobjsense(mosek.objsense.maximize)

            numbarvar = len(dims['s'])
            task.appendbarvars(dims['s'])

            barcsubj, barcsubk, barcsubl = (inds[-1]) * [0], (
                inds[-1]) * [0], (inds[-1]) * [0]
            barcval = [-h[indq[-1] + k] for k in range(inds[0], inds[-1])]
            for s in range(numbarvar):
                for (k, idx) in enumerate(range(inds[s], inds[s + 1])):
                    barcsubk[idx] = k / dims['s'][s]
                    barcsubl[idx] = k % dims['s'][s]
                    barcsubj[idx] = s

            # filter out upper triangular part
            trilidx = [
                idx for idx in range(len(barcsubk))
                if barcsubk[idx] >= barcsubl[idx]
            ]
            barcsubj = [barcsubj[k] for k in trilidx]
            barcsubk = [barcsubk[k] for k in trilidx]
            barcsubl = [barcsubl[k] for k in trilidx]
            barcval = [barcval[k] for k in trilidx]

            task.putbarcblocktriplet(len(trilidx), barcsubj, barcsubk,
                                     barcsubl, barcval)

            Gst = Gs.T
            barasubi = len(Gst) * [0]
            barasubj = len(Gst) * [0]
            barasubk = len(Gst) * [0]
            barasubl = len(Gst) * [0]
            baraval = len(Gst) * [0.0]
            colptr, row, val = Gst.CCS

            for s in range(numbarvar):
                for j in range(ms[s]):
                    for idx in range(colptr[inds[s] + j],
                                     colptr[inds[s] + j + 1]):
                        barasubi[idx] = row[idx]
                        barasubj[idx] = s
                        barasubk[idx] = j / dims['s'][s]
                        barasubl[idx] = j % dims['s'][s]
                        baraval[idx] = val[idx]

            # filter out upper triangular part
            trilidx = [
                idx for (idx, (k, l)) in enumerate(zip(barasubk, barasubl))
                if k >= l
            ]
            barasubi = [barasubi[k] for k in trilidx]
            barasubj = [barasubj[k] for k in trilidx]
            barasubk = [barasubk[k] for k in trilidx]
            barasubl = [barasubl[k] for k in trilidx]
            baraval = [baraval[k] for k in trilidx]

            task.putbarablocktriplet(len(trilidx), barasubi, barasubj,
                                     barasubk, barasubl, baraval)

            for k in range(len(mq)):
                task.appendcone(mosek.conetype.quad, 0.0,
                                range(ml + sum(mq[:k]), ml + sum(mq[:k + 1])))

            if taskfile:
                task.writetask(taskfile)

            task.optimize()

            task.solutionsummary(mosek.streamtype.msg)

            solsta = task.getsolsta(mosek.soltype.itr)

            xu, xl, zq = n * [0.0], n * [0.0], sum(mq) * [0.0]
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.slc, 0, n,
                                  xl)
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.suc, 0, n,
                                  xu)
            task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, ml,
                                  dimx, zq)
            x = matrix(xu) - matrix(xl)
            zq = matrix(zq)

            for s in range(numbarvar):
                xx = (dims['s'][s] * (dims['s'][s] + 1) >> 1) * [0.0]
                task.getbarxj(mosek.soltype.itr, s, xx)

                xs = matrix(0.0, (dims['s'][s], dims['s'][s]))
                idx = 0
                for j in range(dims['s'][s]):
                    for i in range(j, dims['s'][s]):
                        xs[i, j] = xx[idx]
                        if i != j:
                            xs[j, i] = xx[idx]
                        idx += 1

                zq = matrix([zq, xs[:]])

            if ml:
                zl = ml * [0.0]
                task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, 0,
                                      ml, zl)
                zl = matrix(zl)
            else:
                zl = matrix(0.0, (0, 1))

    if (solsta is mosek.solsta.unknown):
        return (solsta, None, None)
    else:
        return (solsta, x, matrix([zl, zq]))
Exemplo n.º 29
0
#########################################################
# Global variables and initialization
def msk_write_log(text):
    sys.stdout.write(text)
    sys.stdout.flush()
    if logfile:
        logfile.write(text)
        logfile.flush()


def msk_print(text):
    msk_write_log(text + '\n')


env = mosek.Env()
task = env.Task()
env.set_Stream(mosek.streamtype.log, msk_write_log)
task.set_Stream(mosek.streamtype.log, msk_write_log)
lastFile = None
logfile = None

welcometext = """
MOSEK Python Console
MOSEK version {0}
Type help for list of commands
Full documentation in the user manual
""".format('.'.join([str(_) for _ in mosek.Env.getversion()]))

helptext = [
    ('help [command]',
Exemplo n.º 30
0
    def solve(self, objective, constraints, cached_data, warm_start, verbose,
              solver_opts):
        """Returns the result of the call to the solver.

        Parameters
        ----------
        objective : LinOp
            The canonicalized objective.
        constraints : list
            The list of canonicalized cosntraints.
        cached_data : dict
            A map of solver name to cached problem data.
        warm_start : bool
            Not used.
        verbose : bool
            Should the solver print output?
        solver_opts : dict
            Additional arguments for the solver.

        Returns
        -------
        tuple
            (status, optimal value, primal, equality dual, inequality dual)
        """
        import mosek
        env = mosek.Env()
        task = env.Task(0, 0)

        if verbose:
            # Define a stream printer to grab output from MOSEK
            def streamprinter(text):
                import sys
                sys.stdout.write(text)
                sys.stdout.flush()

            env.set_Stream(mosek.streamtype.log, streamprinter)
            task.set_Stream(mosek.streamtype.log, streamprinter)

        data = self.get_problem_data(objective, constraints, cached_data)

        A = data[s.A]
        b = data[s.B]
        G = data[s.G]
        h = data[s.H]
        c = data[s.C]
        dims = data[s.DIMS]

        # size of problem
        numvar = len(c) + sum(dims[s.SOC_DIM])
        numcon = len(b) + dims[s.LEQ_DIM] + sum(dims[s.SOC_DIM]) + \
            sum([el**2 for el in dims[s.SDP_DIM]])

        # otherwise it crashes on empty probl.
        if numvar == 0:
            result_dict = {s.STATUS: s.OPTIMAL}
            result_dict[s.PRIMAL] = []
            result_dict[s.VALUE] = 0. + data[s.OFFSET]
            result_dict[s.EQ_DUAL] = []
            result_dict[s.INEQ_DUAL] = []
            return result_dict

        # objective
        task.appendvars(numvar)
        task.putclist(np.arange(len(c)), c)
        task.putvarboundlist(np.arange(numvar, dtype=int),
                             [mosek.boundkey.fr] * numvar, np.zeros(numvar),
                             np.zeros(numvar))

        # SDP variables
        if sum(dims[s.SDP_DIM]) > 0:
            task.appendbarvars(dims[s.SDP_DIM])

        # linear equality and linear inequality constraints
        task.appendcons(numcon)
        if A.shape[0] and G.shape[0]:
            constraints_matrix = sp.bmat([[A], [G]])
        else:
            constraints_matrix = A if A.shape[0] else G
        coefficients = np.concatenate([b, h])

        row, col, el = sp.find(constraints_matrix)
        task.putaijlist(row, col, el)

        type_constraint = [mosek.boundkey.fx] * len(b)
        type_constraint += [mosek.boundkey.up] * dims[s.LEQ_DIM]
        type_constraint += [mosek.boundkey.fx] * (sum(dims[s.SOC_DIM])+ \
                                sum([el**2 for el in dims[s.SDP_DIM]]))

        task.putconboundlist(np.arange(numcon, dtype=int), type_constraint,
                             coefficients, coefficients)

        # cones
        current_var_index = len(c)
        current_con_index = len(b) + dims[s.LEQ_DIM]

        for size_cone in dims[s.SOC_DIM]:
            row, col, el = sp.find(sp.eye(size_cone))
            row += current_con_index
            col += current_var_index
            task.putaijlist(row, col, el)  # add a identity for each cone
            # add a cone constraint
            task.appendcone(
                mosek.conetype.quad,
                0.0,  #unused
                np.arange(current_var_index, current_var_index + size_cone))
            current_con_index += size_cone
            current_var_index += size_cone

        #SDP
        for num_sdp_var, size_matrix in enumerate(dims[s.SDP_DIM]):
            for i_sdp_matrix in range(size_matrix):
                for j_sdp_matrix in range(size_matrix):
                    task.putbaraij(current_con_index, num_sdp_var, [
                        task.appendsparsesymmat(
                            size_matrix, [max(i_sdp_matrix, j_sdp_matrix)],
                            [min(i_sdp_matrix, j_sdp_matrix)],
                            [1. if (i_sdp_matrix == j_sdp_matrix) else .5])
                    ], [1.0])
                    current_con_index += 1

        # solve
        task.putobjsense(mosek.objsense.minimize)
        task.optimize()

        if verbose:
            task.solutionsummary(mosek.streamtype.msg)

        return self.format_results(task, data, cached_data)