Esempio n. 1
0
 def set_linear_coefficients(self, coefficients):
     if self.problem is not None:
         self.problem.update()
         for variable, coefficient in coefficients.items():
             glp_set_obj_coef(self.problem.problem, variable._index, float(coefficient))
         self._expression_expired = True
     else:
         raise Exception("Can't change coefficients if objective is not associated with a model.")
Esempio n. 2
0
def set_objective(lp, c):
    cols_count = len(c)
    glpk.glp_add_cols(lp, cols_count)
    for idx, coef in enumerate(c):
        glpk.glp_set_col_bnds(lp, idx + 1, glpk.GLP_LO, 0.0, 0.0)
        glpk.glp_set_obj_coef(lp, idx + 1, coef)

    return cols_count
Esempio n. 3
0
 def set_linear_coefficients(self, coefficients):
     if self.problem is not None:
         self.problem.update()
         for variable, coefficient in coefficients.items():
             glp_set_obj_coef(self.problem.problem, variable._index, float(coefficient))
         self._expression_expired = True
     else:
         raise Exception("Can't change coefficients if objective is not associated with a model.")
Esempio n. 4
0
    def setFlowObjectiveCoeff(self, flow, coefficient):
        idx = self._getVar(flow)
        self._objective[flow] = coefficient
        glp.glp_set_obj_coef(
            self._lp,
            1 + idx,  # GLPK does 1 indexing
            coefficient)

        self._solved = False
Esempio n. 5
0
    def set_minimize_direction(self, direction):
        '''set the optimization direction'''

        assert len(direction) == self.get_num_cols(), f"expected {self.get_num_cols()} cols, but optimization " + \
            f"vector had {len(direction)} variables"

        for i, d in enumerate(direction):
            col = int(1 + i)

            glpk.glp_set_obj_coef(self.lp, col, float(d))
Esempio n. 6
0
def _linprog(c, A, b, obj):

    lp = glpk.glp_create_prob()
    glpk.glp_set_obj_dir(lp, obj)

    params = glpk.glp_smcp()
    glpk.glp_init_smcp(params)
    params.msg_lev = glpk.GLP_MSG_OFF  #Only print error messages from GLPK

    num_rows = A.shape[0]
    num_cols = A.shape[1]
    mat_size = num_rows * num_cols

    glpk.glp_add_rows(lp, num_rows)

    for row_ind in range(num_rows):
        glpk.glp_set_row_bnds(lp, row_ind + 1, glpk.GLP_UP, 0.0,
                              float(b[row_ind]))

    glpk.glp_add_cols(lp, num_cols)

    for col_ind in range(num_cols):
        glpk.glp_set_col_bnds(lp, col_ind + 1, glpk.GLP_FR, 0.0, 0.0)
        glpk.glp_set_obj_coef(lp, col_ind + 1, c[col_ind])

    'Swig arrays are used for feeding constraints in GLPK'

    ia, ja, ar = [], [], []
    for i, j in product(range(num_rows), range(num_cols)):
        ia.append(i + 1)
        ja.append(j + 1)
        ar.append(float(A[i][j]))

    ia = glpk.as_intArray(ia)
    ja = glpk.as_intArray(ja)
    ar = glpk.as_doubleArray(ar)

    glpk.glp_load_matrix(lp, mat_size, ia, ja, ar)
    glpk.glp_simplex(lp, params)

    fun = glpk.glp_get_obj_val(lp)
    x = [
        i for i in map(lambda x: glpk.glp_get_col_prim(lp, x + 1),
                       range(num_cols))
    ]

    glpk.glp_delete_prob(lp)
    glpk.glp_free_env()

    return LPSolution(x, fun)
Esempio n. 7
0
 def objective(self, value):
     value.problem = None
     if self._objective is not None:
         for variable in self.objective.variables:
             if variable.index is not None:
                 glp_set_obj_coef(self.problem, variable.index, 0.)
     super(Model, self.__class__).objective.fset(self, value)
     self.update()
     expression = self._objective._expression
     if isinstance(expression, float) or isinstance(expression, int) or expression.is_Number:
         pass
     else:
         if expression.is_Symbol:
             glp_set_obj_coef(self.problem, expression.index, 1.)
         if expression.is_Mul:
             coeff, var = expression.args
             glp_set_obj_coef(self.problem, var.index, float(coeff))
         elif expression.is_Add:
             for term in expression.args:
                 coeff, var = term.args
                 glp_set_obj_coef(self.problem, var.index, float(coeff))
         else:
             raise ValueError(
                 "Provided objective %s doesn't seem to be appropriate." %
                 self._objective)
         glp_set_obj_dir(
             self.problem,
             {'min': GLP_MIN, 'max': GLP_MAX}[self._objective.direction]
         )
     value.problem = self
Esempio n. 8
0
def setup_col(
    problem: SwigPyObject,
    j: int,
    recipe: 'Recipe',
    resource_indices: Dict[str, int],
    min_clock: Optional[int] = None,
    fixed_clock: Optional[int] = None,
):
    lp.glp_set_col_name(problem, j, recipe.name)

    # The game's clock scaling resolution is one percentage point, so we
    # ask for integers with an implicit scale of 100
    lp.glp_set_col_kind(problem, j, lp.GLP_IV)

    # All recipes are currently weighed the same
    lp.glp_set_obj_coef(problem, j, 1)

    if fixed_clock is None:
        # All recipes must have at least 0 instances
        lp.glp_set_col_bnds(
            problem,
            j,
            lp.GLP_LO,
            min_clock or 0,
            float('inf'),  # Lower and upper boundaries
        )
    else:
        # Set our desired (fixed) outputs
        lp.glp_set_col_bnds(
            problem,
            j,
            lp.GLP_FX,
            fixed_clock,
            fixed_clock,  # Boundaries are equal (variable is fixed)
        )

    # The constraint coefficients are just the recipe rates
    n_sparse = len(recipe.rates)
    ind = lp.intArray(n_sparse + 1)
    val = lp.doubleArray(n_sparse + 1)
    for i, (resource, rate) in enumerate(recipe.rates.items(), 1):
        ind[i] = resource_indices[resource]
        val[i] = rate
    lp.glp_set_mat_col(problem, j, n_sparse, ind, val)
Esempio n. 9
0
    def objective(self, value):
        value.problem = None
        if self._objective is not None:
            variables = self.objective.variables
            for variable in variables:
                if variable._index is not None:
                    glp_set_obj_coef(self.problem, variable._index, 0.)
        super(Model, self.__class__).objective.fset(self, value)
        self.update()

        coef_dict, _ = parse_optimization_expression(value, linear=True)

        for var, coef in coef_dict.items():
            glp_set_obj_coef(self.problem, var._index, float(coef))

        glp_set_obj_dir(self.problem, {
            'min': GLP_MIN,
            'max': GLP_MAX
        }[self._objective.direction])
        value.problem = self
Esempio n. 10
0
    def objective(self, value):
        value.problem = None
        if self._objective is not None:
            variables = self.objective.variables
            for variable in variables:
                if variable._index is not None:
                    glp_set_obj_coef(self.problem, variable._index, 0.)
        super(Model, self.__class__).objective.fset(self, value)
        self.update()

        coef_dict, _ = parse_optimization_expression(value, linear=True)

        for var, coef in coef_dict.items():
            glp_set_obj_coef(self.problem, var._index, float(coef))

        glp_set_obj_dir(
            self.problem,
            {'min': GLP_MIN, 'max': GLP_MAX}[self._objective.direction]
        )
        value.problem = self
	def test_swiglpk(self):
		"""Test the underlying GLPK lib and its SWIG interface based on
		the example from https://github.com/biosustain/swiglpk
		"""
		ia = glp.intArray(1 + 1000)
		ja = glp.intArray(1 + 1000)
		ar = glp.doubleArray(1 + 1000)

		lp = glp.glp_create_prob()
		smcp = glp.glp_smcp()
		glp.glp_init_smcp(smcp)
		smcp.msg_lev = glp.GLP_MSG_ALL  # use GLP_MSG_ERR?

		glp.glp_set_prob_name(lp, "sample")
		glp.glp_set_obj_dir(lp, glp.GLP_MAX)

		glp.glp_add_rows(lp, 3)
		glp.glp_set_row_name(lp, 1, "p")
		glp.glp_set_row_bnds(lp, 1, glp.GLP_UP, 0.0, 100.0)
		glp.glp_set_row_name(lp, 2, "q")
		glp.glp_set_row_bnds(lp, 2, glp.GLP_UP, 0.0, 600.0)
		glp.glp_set_row_name(lp, 3, "r")
		glp.glp_set_row_bnds(lp, 3, glp.GLP_UP, 0.0, 300.0)
		glp.glp_add_cols(lp, 3)
		glp.glp_set_col_name(lp, 1, "x1")
		glp.glp_set_col_bnds(lp, 1, glp.GLP_LO, 0.0, 0.0)
		glp.glp_set_obj_coef(lp, 1, 10.0)
		glp.glp_set_col_name(lp, 2, "x2")
		glp.glp_set_col_bnds(lp, 2, glp.GLP_LO, 0.0, 0.0)
		glp.glp_set_obj_coef(lp, 2, 6.0)
		glp.glp_set_col_name(lp, 3, "x3")
		glp.glp_set_col_bnds(lp, 3, glp.GLP_LO, 0.0, 0.0)
		glp.glp_set_obj_coef(lp, 3, 4.0)

		ia[1] = 1; ja[1] = 1; ar[1] = 1.0  # a[1,1] = 1
		ia[2] = 1; ja[2] = 2; ar[2] = 1.0  # a[1,2] = 1
		ia[3] = 1; ja[3] = 3; ar[3] = 1.0  # a[1,3] = 1
		ia[4] = 2; ja[4] = 1; ar[4] = 10.0  # a[2,1] = 10
		ia[5] = 3; ja[5] = 1; ar[5] = 2.0  # a[3,1] = 2
		ia[6] = 2; ja[6] = 2; ar[6] = 4.0  # a[2,2] = 4
		ia[7] = 3; ja[7] = 2; ar[7] = 2.0  # a[3,2] = 2
		ia[8] = 2; ja[8] = 3; ar[8] = 5.0  # a[2,3] = 5
		ia[9] = 3; ja[9] = 3; ar[9] = 6.0  # a[3,3] = 6

		glp.glp_load_matrix(lp, 9, ia, ja, ar)
		glp.glp_simplex(lp, smcp)

		Z = glp.glp_get_obj_val(lp)
		x1 = glp.glp_get_col_prim(lp, 1)
		x2 = glp.glp_get_col_prim(lp, 2)
		x3 = glp.glp_get_col_prim(lp, 3)

		self.assertAlmostEqual(Z, 733.3333, 4)
		self.assertAlmostEqual(x1, 33.3333, 4)
		self.assertAlmostEqual(x2, 66.6667, 4)
		self.assertAlmostEqual(x3, 0)

		glp.glp_delete_prob(lp)
Esempio n. 12
0
    def set_minimize_direction(self, direction_vec, is_csr=False, offset=None):
        '''set the direction for the optimization

        if offset is None, will use cur_vars_offset (direction is in terms of current-time variables)
        '''

        Timers.tic("set_minimize_direction")

        if offset is None:
            offset = self.cur_vars_offset

            size = direction_vec.shape[1] if is_csr else len(direction_vec)

            assert size <= self.dims, "len(direction_vec) ({}) > number of cur_vars({})".format(
                size, self.dims)
        else:
            assert direction_vec.shape[1] + offset <= self.get_num_cols()

        # set the previous objective columns to zero
        for i in self.obj_cols:
            glpk.glp_set_obj_coef(self.lp, i, 0)

        self.obj_cols = []

        if is_csr:
            assert isinstance(direction_vec, csr_matrix)
            assert direction_vec.shape[0] == 1

            data, inds, indptr = direction_vec.data, direction_vec.indices, direction_vec.indptr
            
            for n in range(indptr[1]):
                col = int(1 + offset + inds[n])
                self.obj_cols.append(col)

                if col > len(self.names):
                    print(self)
                    
                assert col <= len(self.names) 
                glpk.glp_set_obj_coef(self.lp, col, data[n])

        else: # non-csr
            if not isinstance(direction_vec, np.ndarray):
                direction_vec = np.array(direction_vec, dtype=float)

            assert len(direction_vec.shape) == 1
            assert len(direction_vec) <= self.dims, "dirLen({}) > dims({})".format(len(direction_vec), self.dims)

            for i, direction in enumerate(direction_vec):
                col = int(1 + offset + i)
                self.obj_cols.append(col)
                glpk.glp_set_obj_coef(self.lp, col, float(direction))

        Timers.toc("set_minimize_direction")
Esempio n. 13
0
    def set_objective(self, expression):
        """Set objective of problem."""

        if isinstance(expression, numbers.Number):
            # Allow expressions with no variables as objective,
            # represented as a number
            expression = Expression(offset=expression)

        # Clear previous objective
        for i in range(swiglpk.glp_get_num_cols(self._p)):
            swiglpk.glp_set_obj_coef(self._p, 1 + i, 0)

        for variable, value in expression.values():
            var_index = self._variables[variable]
            swiglpk.glp_set_obj_coef(self._p, var_index, value)

        swiglpk.glp_set_obj_coef(self._p, 0, expression.offset)
Esempio n. 14
0
File: glpk.py Progetto: jonls/psamm
    def set_objective(self, expression):
        """Set objective of problem."""

        if isinstance(expression, numbers.Number):
            # Allow expressions with no variables as objective,
            # represented as a number
            expression = Expression(offset=expression)

        # Clear previous objective
        for i in range(swiglpk.glp_get_num_cols(self._p)):
            swiglpk.glp_set_obj_coef(self._p, 1 + i, 0)

        for variable, value in expression.values():
            var_index = self._variables[variable]
            swiglpk.glp_set_obj_coef(self._p, var_index, value)

        swiglpk.glp_set_obj_coef(self._p, 0, expression.offset)
Esempio n. 15
0
 def set_linear_coefficients(self, coefficients):
     for variable, coefficient in coefficients.items():
         glp_set_obj_coef(self.problem.problem, variable._index,
                          coefficient)
     self._expression_expired = True
Esempio n. 16
0
    def _import_problem(self):
        import swiglpk as glpk

        if self.verbosity() >= 1:
            glpk.glp_term_out(glpk.GLP_ON)
        else:
            glpk.glp_term_out(glpk.GLP_OFF)

        # Create a problem instance.
        p = self.int = glpk.glp_create_prob();

        # Set the objective.
        if self.ext.objective[0] in ("find", "min"):
            glpk.glp_set_obj_dir(p, glpk.GLP_MIN)
        elif self.ext.objective[0] is "max":
            glpk.glp_set_obj_dir(p, glpk.GLP_MAX)
        else:
            raise NotImplementedError("Objective '{0}' not supported by GLPK."
                .format(self.ext.objective[0]))

        # Set objective function shift
        if self.ext.objective[1] is not None \
        and self.ext.objective[1].constant is not None:
            if not isinstance(self.ext.objective[1], AffinExp):
                raise NotImplementedError("Non-linear objective function not "
                    "supported by GLPK.")

            if self.ext.objective[1].constant.size != (1,1):
                raise NotImplementedError("Non-scalar objective function not "
                    "supported by GLPK.")

            glpk.glp_set_obj_coef(p, 0, self.ext.objective[1].constant[0])

        # Add variables.
        # Multideminsional variables are split into multiple scalar variables
        # represented as matrix columns within GLPK.
        for varName in self.ext.varNames:
            var = self.ext.variables[varName]

            # Add a column for every scalar variable.
            numCols = var.size[0] * var.size[1]
            glpk.glp_add_cols(p, numCols)

            for localIndex, picosIndex \
            in enumerate(range(var.startIndex, var.endIndex)):
                glpkIndex = self._picos2glpk_variable_index(picosIndex)

                # Assign a name to the scalar variable.
                scalarName = varName
                if numCols > 1:
                    x = localIndex // var.size[0]
                    y = localIndex % var.size[0]
                    scalarName += "_{:d}_{:d}".format(x + 1, y + 1)
                glpk.glp_set_col_name(p, glpkIndex, scalarName)

                # Assign bounds to the scalar variable.
                lower, upper = var.bnd.get(localIndex, (None, None))
                if lower is not None and upper is not None:
                    if lower == upper:
                        glpk.glp_set_col_bnds(
                            p, glpkIndex, glpk.GLP_FX, lower, upper)
                    else:
                        glpk.glp_set_col_bnds(
                            p, glpkIndex, glpk.GLP_DB, lower, upper)
                elif lower is not None and upper is None:
                    glpk.glp_set_col_bnds(p, glpkIndex, glpk.GLP_LO, lower, 0)
                elif lower is None and upper is not None:
                    glpk.glp_set_col_bnds(p, glpkIndex, glpk.GLP_UP, 0, upper)
                else:
                    glpk.glp_set_col_bnds(p, glpkIndex, glpk.GLP_FR, 0, 0)

                # Assign a type to the scalar variable.
                if var.vtype in ("continuous", "symmetric"):
                    glpk.glp_set_col_kind(p, glpkIndex, glpk.GLP_CV)
                elif var.vtype == "integer":
                    glpk.glp_set_col_kind(p, glpkIndex, glpk.GLP_IV)
                elif var.vtype == "binary":
                    glpk.glp_set_col_kind(p, glpkIndex, glpk.GLP_BV)
                else:
                    raise NotImplementedError("Variable type '{0}' not "
                        "supported by GLPK.".format(var.vtype()))

                # Set objective function coefficient of the scalar variable.
                if self.ext.objective[1] is not None \
                and var in self.ext.objective[1].factors:
                    glpk.glp_set_obj_coef(p, glpkIndex,
                        self.ext.objective[1].factors[var][localIndex])

        # Add constraints.
        # Multideminsional constraints are split into multiple scalar
        # constraints represented as matrix rows within GLPK.
        rowOffset = 1
        for constraintNum, constraint in enumerate(self.ext.constraints):
            if not isinstance(constraint, AffineConstraint):
                raise NotImplementedError(
                    "Non-linear constraints not supported by GLPK.")

            # Add a row for every scalar constraint.
            # Internally, GLPK uses an auxiliary variable for every such row,
            # bounded by the right hand side of the scalar constraint in a
            # canonical form.
            numRows = len(constraint)
            glpk.glp_add_rows(p, numRows)

            self._debug("Handling PICOS Constraint: " + str(constraint))

            # Split multidimensional constraints into multiple scalar ones.
            for localConIndex, (glpkVarIndices, coefficients, rhs) in \
                    enumerate(constraint.sparse_Ab_rows(
                    None, indexFunction = lambda picosVar, i:
                    self._picos2glpk_variable_index(picosVar.startIndex + i))):
                # Determine GLPK's row index of the scalar constraint.
                glpkConIndex = rowOffset + localConIndex
                numColumns   = len(glpkVarIndices)

                # Name the auxiliary variable associated with the current row.
                if constraint.name:
                    name = constraint.name
                else:
                    name = "rhs_{:d}".format(constraintNum)
                if numRows > 1:
                    x = localConIndex // constraint.size[0]
                    y = localConIndex % constraint.size[0]
                    name += "_{:d}_{:d}".format(x + 1, y + 1)
                glpk.glp_set_row_name(p, glpkConIndex, name)

                # Assign bounds to the auxiliary variable.
                if constraint.is_equality():
                    glpk.glp_set_row_bnds(p, glpkConIndex, glpk.GLP_FX, rhs,rhs)
                elif constraint.is_increasing():
                    glpk.glp_set_row_bnds(p, glpkConIndex, glpk.GLP_UP, 0, rhs)
                elif constraint.is_decreasing():
                    glpk.glp_set_row_bnds(p, glpkConIndex, glpk.GLP_LO, rhs, 0)
                else:
                    assert False, "Unexpected constraint relation."

                # Set coefficients for current row.
                # Note that GLPK requires a glpk.intArray containing column
                # indices and a glpk.doubleArray of same size containing the
                # coefficients for the listed column index. The first element
                # of both arrays (with index 0) is skipped by GLPK.
                glpkVarIndicesArray = glpk.intArray(numColumns + 1)
                for i in range(numColumns):
                    glpkVarIndicesArray[i + 1] = glpkVarIndices[i]

                coefficientsArray = glpk.doubleArray(numColumns + 1)
                for i in range(numColumns):
                    coefficientsArray[i + 1] = coefficients[i]

                glpk.glp_set_mat_row(p, glpkConIndex, numColumns,
                    glpkVarIndicesArray, coefficientsArray)

            rowOffset += numRows
Esempio n. 17
0
 def set_linear_coefficients(self, coefficients):
     for variable, coefficient in coefficients.items():
         glp_set_obj_coef(self.problem.problem, variable._index, coefficient)
     self._expression_expired = True
Esempio n. 18
0
 def _set_linear_objective_term(self, variable, coefficient):
     glp_set_obj_coef(self.problem, variable.index, coefficient)