Ejemplo n.º 1
0
 def _initialize_problem(self):
     self.problem = glp_create_prob()
     glp_create_index(self.problem)
     glp_scale_prob(self.problem, GLP_SF_AUTO)
     if self.name is not None:
         _glpk_validate_id(self.name)
         glp_set_prob_name(self.problem, str(self.name))
	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)
Ejemplo n.º 3
0
def setup_linprog(
    recipes: Dict[str, 'Recipe'],
    min_rates: Optional[Dict[str, float]] = None,
    min_clocks: Optional[Dict[str, int]] = None,
    fixed_clocks: Optional[Dict[str, int]] = None,
) -> SwigPyObject:
    if min_rates is None:
        min_rates = {}
    if min_clocks is None:
        min_clocks = {}
    if fixed_clocks is None:
        fixed_clocks = {}

    resources = sorted({p for r in recipes.values() for p in r.rates.keys()})
    resource_indices: Dict[str,
                           int] = {r: i
                                   for i, r in enumerate(resources, 1)}
    m = len(resources)
    n = len(recipes)

    problem: SwigPyObject = lp.glp_create_prob()
    lp.glp_set_prob_name(problem, 'satisfactory')
    lp.glp_set_obj_name(problem, 'percentage_sum')
    lp.glp_set_obj_dir(problem, lp.GLP_MIN)
    lp.glp_add_rows(problem, m)
    lp.glp_add_cols(problem, n)

    for i, resource in enumerate(resources, 1):
        setup_row(problem, i, resource, min_rates.get(resource, 0))

    for j, recipe in enumerate(recipes.values(), 1):
        setup_col(
            problem,
            j,
            recipe,
            resource_indices,
            min_clocks.get(recipe.name),
            fixed_clocks.get(recipe.name),
        )

    lp.glp_create_index(problem)

    return problem
Ejemplo n.º 4
0
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        self.configuration = Configuration()

        if problem is None:
            self.problem = glp_create_prob()
            glp_create_index(self.problem)
            if self.name is not None:
                glp_set_prob_name(self.problem, str(self.name))

        else:
            try:
                self.problem = problem
                glp_create_index(self.problem)
            except TypeError:
                raise TypeError("Provided problem is not a valid GLPK model.")
            row_num = glp_get_num_rows(self.problem)
            col_num = glp_get_num_cols(self.problem)
            for i in range(1, col_num + 1):
                var = Variable(glp_get_col_name(self.problem, i),
                               lb=glp_get_col_lb(self.problem, i),
                               ub=glp_get_col_ub(self.problem, i),
                               problem=self,
                               type=_GLPK_VTYPE_TO_VTYPE[glp_get_col_kind(
                                   self.problem, i)])
                # This avoids adding the variable to the glpk problem
                super(Model, self)._add_variables([var])
            variables = self.variables

            for j in range(1, row_num + 1):
                ia = intArray(col_num + 1)
                da = doubleArray(col_num + 1)
                nnz = glp_get_mat_row(self.problem, j, ia, da)
                constraint_variables = [
                    variables[ia[i] - 1] for i in range(1, nnz + 1)
                ]

                # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
                # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1]
                #                         for i in range(1, nnz + 1)])
                lhs = 0

                glpk_row_type = glp_get_row_type(self.problem, j)
                if glpk_row_type == GLP_FX:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = row_lb
                elif glpk_row_type == GLP_LO:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = None
                elif glpk_row_type == GLP_UP:
                    row_lb = None
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_DB:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_FR:
                    row_lb = None
                    row_ub = None
                else:
                    raise Exception(
                        "Currently, optlang does not support glpk row type %s"
                        % str(glpk_row_type))
                    log.exception()
                if isinstance(lhs, int):
                    lhs = sympy.Integer(lhs)
                elif isinstance(lhs, float):
                    lhs = sympy.RealNumber(lhs)
                constraint_id = glp_get_row_name(self.problem, j)
                for variable in constraint_variables:
                    try:
                        self._variables_to_constraints_mapping[
                            variable.name].add(constraint_id)
                    except KeyError:
                        self._variables_to_constraints_mapping[
                            variable.name] = set([constraint_id])

                super(Model, self)._add_constraints([
                    Constraint(lhs,
                               lb=row_lb,
                               ub=row_ub,
                               name=constraint_id,
                               problem=self,
                               sloppy=True)
                ],
                                                    sloppy=True)

            term_generator = ((glp_get_obj_coef(self.problem,
                                                index), variables[index - 1])
                              for index in range(1,
                                                 glp_get_num_cols(problem) +
                                                 1))
            self._objective = Objective(_unevaluated_Add(*[
                _unevaluated_Mul(sympy.RealNumber(term[0]), term[1])
                for term in term_generator if term[0] != 0.
            ]),
                                        problem=self,
                                        direction={
                                            GLP_MIN: 'min',
                                            GLP_MAX: 'max'
                                        }[glp_get_obj_dir(self.problem)])
        glp_scale_prob(self.problem, GLP_SF_AUTO)
Ejemplo n.º 5
0
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        self.configuration = Configuration()

        if problem is None:
            self.problem = glp_create_prob()
            glp_create_index(self.problem)
            if self.name is not None:
                glp_set_prob_name(self.problem, str(self.name))

        else:
            try:
                self.problem = problem
                glp_create_index(self.problem)
            except TypeError:
                raise TypeError("Provided problem is not a valid GLPK model.")
            row_num = glp_get_num_rows(self.problem)
            col_num = glp_get_num_cols(self.problem)
            for i in range(1, col_num + 1):
                var = Variable(
                    glp_get_col_name(self.problem, i),
                    lb=glp_get_col_lb(self.problem, i),
                    ub=glp_get_col_ub(self.problem, i),
                    problem=self,
                    type=_GLPK_VTYPE_TO_VTYPE[
                        glp_get_col_kind(self.problem, i)]
                )
                # This avoids adding the variable to the glpk problem
                super(Model, self)._add_variables([var])
            variables = self.variables

            for j in range(1, row_num + 1):
                ia = intArray(col_num + 1)
                da = doubleArray(col_num + 1)
                nnz = glp_get_mat_row(self.problem, j, ia, da)
                constraint_variables = [variables[ia[i] - 1] for i in range(1, nnz + 1)]

                # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
                # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1]
                #                         for i in range(1, nnz + 1)])
                lhs = 0

                glpk_row_type = glp_get_row_type(self.problem, j)
                if glpk_row_type == GLP_FX:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = row_lb
                elif glpk_row_type == GLP_LO:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = None
                elif glpk_row_type == GLP_UP:
                    row_lb = None
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_DB:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_FR:
                    row_lb = None
                    row_ub = None
                else:
                    raise Exception(
                        "Currently, optlang does not support glpk row type %s"
                        % str(glpk_row_type)
                    )
                    log.exception()
                if isinstance(lhs, int):
                    lhs = sympy.Integer(lhs)
                elif isinstance(lhs, float):
                    lhs = sympy.RealNumber(lhs)
                constraint_id = glp_get_row_name(self.problem, j)
                for variable in constraint_variables:
                    try:
                        self._variables_to_constraints_mapping[variable.name].add(constraint_id)
                    except KeyError:
                        self._variables_to_constraints_mapping[variable.name] = set([constraint_id])

                super(Model, self)._add_constraints(
                    [Constraint(lhs, lb=row_lb, ub=row_ub, name=constraint_id, problem=self, sloppy=True)],
                    sloppy=True
                )

            term_generator = (
                (glp_get_obj_coef(self.problem, index), variables[index - 1])
                for index in range(1, glp_get_num_cols(problem) + 1)
            )
            self._objective = Objective(
                _unevaluated_Add(
                    *[_unevaluated_Mul(sympy.RealNumber(term[0]), term[1]) for term in term_generator if
                      term[0] != 0.]),
                problem=self,
                direction={GLP_MIN: 'min', GLP_MAX: 'max'}[glp_get_obj_dir(self.problem)])
        glp_scale_prob(self.problem, GLP_SF_AUTO)