Пример #1
0
    def _process_rhs(self, data_line: DataLine):
        if len(self._rhs) != len(self.constraint_names):
            self._rhs = np.zeros(len(self.constraint_names))

        self._add_rhs(data_line.second_name(), data_line.first_number())

        if data_line.has_third_name() and data_line.has_second_number():
            self._add_rhs(data_line.third_name(), data_line.second_number())
Пример #2
0
def test_first_number_column(line, expected):
    """
    The first numeric field is the 25-36 column range (inclusive).
    """
    padding = " " * 24  # starts at column 25, so 24 spaces.
    data_line = DataLine(padding + line)

    assert_almost_equal(data_line.first_number(), expected)
Пример #3
0
    def _process_scenarios(self, data_line: DataLine):
        if data_line.indicator() == "SC":  # new scenario
            scen = Scenario(data_line.first_name(), data_line.second_name(),
                            data_line.third_name(), data_line.first_number())

            self._current_scen = scen
            return

        var = data_line.first_name()
        constr = data_line.second_name()
        value = data_line.first_number()

        assert self._current_scen is not None
        self._current_scen.add_modification(constr, var, value)

        if data_line.has_third_name() and data_line.has_second_number():
            constr = data_line.third_name()
            value = data_line.second_number()

            self._current_scen.add_modification(constr, var, value)
Пример #4
0
def test_first_data_entry():
    """
    Tests if the DataLine class correctly parses the first data entry.
    """
    # From the sslp_5_25_50.cor file.
    line = "    x_1       c2                 188"
    data_line = DataLine(line)

    assert_equal(data_line.first_name(), "x_1")
    assert_equal(data_line.second_name(), "c2")
    assert_almost_equal(data_line.first_number(), 188)
Пример #5
0
    def _parse_column(self, data_line: DataLine):
        var = data_line.first_name()

        if var not in self._var2idx:
            self._variable_names.append(var)
            self._types.append('I' if self._parse_ints else 'C')
            self._var2idx[var] = len(self._variable_names) - 1

        constr = data_line.second_name()
        value = data_line.first_number()
        self._add_value(constr, var, value)

        if data_line.has_third_name() and data_line.has_second_number():
            constr = data_line.third_name()
            value = data_line.second_number()
            self._add_value(constr, var, value)
Пример #6
0
    def _process_bounds(self, data_line: DataLine):
        """
        There are a ton of bound types, but the most common are listed below,
        originally due to http://lpsolve.sourceforge.net/5.5/mps-format.htm. A
        bound is specified by a two-letter type and a value b.

        - LO    lower bound        b <= x (< +inf)
        - UP    upper bound        (0 <=) x <= b
        - FX    fixed variable     x = b
        - FR    free variable      -inf < x < +inf
        - MI    lower bound -inf   -inf < x (<= 0)
        - PL    upper bound +inf   (0 <=) x < +inf
        - BV    binary variable    x = 0 or 1
        - LI    integer variable   b <= x (< +inf)
        - UI    integer variable   (0 <=) x <= b

        Raises
        ------
        ValueError
            When the bound type is not understood.
        """
        if len(self._lb) != len(self.variable_names) != len(self._ub):
            self._lb = np.zeros(len(self.variable_names))
            self._ub = np.full(len(self.variable_names), np.inf)

        bound_type = data_line.indicator()

        if bound_type not in _BOUNDS_TYPES:
            msg = f"Bounds of type {bound_type} are not understood."
            logger.error(msg)
            raise ValueError(msg)

        var = data_line.second_name()
        idx = self._var2idx[var]

        # The value is clear from the type, and need not have been specified.
        # Hence we treat these separately, and then return.
        if bound_type in {"FR", "MI", "PL", "BV"}:
            if bound_type == "FR":  # free variable
                self._lb[idx] = -np.inf
                self._ub[idx] = np.inf

            if bound_type == "MI":  # -inf lower bound
                self._lb[idx] = -np.inf

            if bound_type == "PL":  # +inf upper bound
                self._ub[idx] = np.inf

            if bound_type == "BV":  # binary variable
                self._lb[idx] = 0
                self._ub[idx] = 1
                self._types[idx] = 'B'

            return

        value = data_line.first_number()

        if bound_type == "LO":  # lower bound
            self._lb[idx] = value

        if bound_type == "UP":  # upper bound
            self._ub[idx] = value

        if bound_type == "FX":  # fixed variable
            self._lb[idx] = value
            self._ub[idx] = value

        if bound_type == "LI":  # integer variable, lower bound
            self._lb[idx] = value
            self._types[idx] = 'I'

        if bound_type == "UI":  # integer variable, upper bound
            self._ub[idx] = value
            self._types[idx] = 'I'