Esempio n. 1
0
    def get_col_bounds(self):
        'get column bounds'

        lp_cols = self.get_num_cols()

        # column lower and upper bounds
        col_bounds = []

        for col in range(lp_cols):
            col_type = glpk.glp_get_col_type(self.lp, col + 1)

            ub = np.inf
            lb = -np.inf

            if col_type == glpk.GLP_DB:
                ub = glpk.glp_get_col_ub(self.lp, col + 1)
                lb = glpk.glp_get_col_lb(self.lp, col + 1)
            elif col_type == glpk.GLP_LO:
                lb = glpk.glp_get_col_lb(self.lp, col + 1)
            elif col_type == glpk.GLP_FX:
                lb = ub = glpk.glp_get_col_lb(self.lp, col + 1)
            else:
                assert col_type == glpk.GLP_FR, "unsupported col type in get_col_bounds()"

            col_bounds.append((lb, ub))

        return col_bounds
Esempio n. 2
0
 def test_change_variable_bounds(self):
     inner_prob = self.model.problem
     inner_problem_bounds = [(glp_get_col_lb(inner_prob, i), glp_get_col_ub(inner_prob, i)) for i in
                             range(1, glp_get_num_cols(inner_prob) + 1)]
     bounds = [(var.lb, var.ub) for var in self.model.variables.values()]
     self.assertEqual(bounds, inner_problem_bounds)
     for var in self.model.variables.values():
         var.lb = random.uniform(-1000, 1000)
         var.ub = random.uniform(var.lb, 1000)
     inner_problem_bounds_new = [(glp_get_col_lb(inner_prob, i), glp_get_col_ub(inner_prob, i)) for i in
                                 range(1, glp_get_num_cols(inner_prob) + 1)]
     bounds_new = [(var.lb, var.ub) for var in self.model.variables.values()]
     self.assertNotEqual(bounds, bounds_new)
     self.assertNotEqual(inner_problem_bounds, inner_problem_bounds_new)
     self.assertEqual(bounds_new, inner_problem_bounds_new)
Esempio n. 3
0
 def test_glpk_setting_bounds(self):
     self.model.add(self.var)
     self.model.update()
     var = self.var
     model = self.model
     var.lb = 1
     self.assertEqual(var.lb, 1)
     self.assertEqual(glp_get_col_lb(model.problem, var._index), 1)
     var.ub = 2
     self.assertEqual(var.ub, 2)
     self.assertEqual(glp_get_col_ub(model.problem, var._index), 2)
Esempio n. 4
0
 def test_glpk_setting_bounds(self):
     self.model.add(self.var)
     self.model.update()
     var = self.var
     model = self.model
     var.lb = 1
     self.assertEqual(var.lb, 1)
     self.assertEqual(glp_get_col_lb(model.problem, var._index), 1)
     var.ub = 2
     self.assertEqual(var.ub, 2)
     self.assertEqual(glp_get_col_ub(model.problem, var._index), 2)
 def test_change_variable_bounds(self):
     inner_prob = self.model.problem
     inner_problem_bounds = [
         (glp_get_col_lb(inner_prob, i), glp_get_col_ub(inner_prob, i))
         for i in range(1,
                        glp_get_num_cols(inner_prob) + 1)
     ]
     bounds = [(var.lb, var.ub) for var in self.model.variables.values()]
     self.assertEqual(bounds, inner_problem_bounds)
     for var in self.model.variables.values():
         var.lb = random.uniform(-1000, 1000)
         var.ub = random.uniform(var.lb, 1000)
     inner_problem_bounds_new = [
         (glp_get_col_lb(inner_prob, i), glp_get_col_ub(inner_prob, i))
         for i in range(1,
                        glp_get_num_cols(inner_prob) + 1)
     ]
     bounds_new = [(var.lb, var.ub)
                   for var in self.model.variables.values()]
     self.assertNotEqual(bounds, bounds_new)
     self.assertNotEqual(inner_problem_bounds, inner_problem_bounds_new)
     self.assertEqual(bounds_new, inner_problem_bounds_new)
Esempio n. 6
0
    def _column_names_str(self):
        'get the line in __str__ for the column names'

        rv = "   "
        dbl_max = sys.float_info.max

        for col, name in enumerate(self.names):
            name = self.names[col]

            lb = glpk.glp_get_col_lb(self.lp, col + 1)
            ub = glpk.glp_get_col_ub(self.lp, col + 1)

            if lb != -dbl_max or ub != dbl_max:
                name = "*" + name

            name = name.rjust(6)[:6]  # fix width to exactly 6

            rv += name + " "

        rv += "\n"

        return rv
Esempio n. 7
0
    def _var_bounds_str(self):
        'get the variable bounds string used in __str__'

        rv = ""

        dbl_max = sys.float_info.max
        added_label = False

        for index, name in enumerate(self.names):
            lb = glpk.glp_get_col_lb(self.lp, index + 1)
            ub = glpk.glp_get_col_ub(self.lp, index + 1)

            if not added_label and (lb != -dbl_max or ub != dbl_max):
                added_label = True
                rv += "(*) Bounded variables:"

            if lb != -dbl_max or ub != dbl_max:
                lb = "-inf" if lb == -dbl_max else lb
                ub = "inf" if ub == dbl_max else ub

                rv += f"\n{name} in [{lb}, {ub}]"

        return rv
Esempio n. 8
0
    def _initialize_model_from_problem(self, problem):
        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 = symbolics.Integer(lhs)
            elif isinstance(lhs, float):
                lhs = symbolics.Real(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(
            symbolics.add(
                [symbolics.mul((symbolics.Real(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)
Esempio n. 9
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)