示例#1
0
def find_transform(x, y, limit, threshold=1e-7):
    """
    find a integer solution to ax + b - cxy - dy = 0
    this will give us the mobius transform: T(x) = y
    :param x: numeric constant to check
    :param y: numeric manipulation of constant
    :param limit: range to look at
    :param threshold: optimal solution threshold.
    :return MobiusTransform in case of success or None.
    """
    x1 = x
    x2 = dec(1.0)
    x3 = -x * y
    x4 = -y
    solver = Solver('mobius', Solver.CBC_MIXED_INTEGER_PROGRAMMING)
    a = solver.IntVar(-limit, limit, 'a')
    b = solver.IntVar(-limit, limit, 'b')
    c = solver.IntVar(-limit, limit, 'c')
    d = solver.IntVar(-limit, limit, 'd')
    f = solver.NumVar(0, 1, 'f')
    solver.Add(f == (a * x1 + b * x2 + c * x3 + d * x4))
    solver.Add(a * x1 + b >=
               1)  # don't except trivial solutions and remove some redundancy
    solver.Minimize(f)
    status = solver.Solve()
    if status == Solver.OPTIMAL:
        if abs(solver.Objective().Value()) <= threshold:
            res_a, res_b, res_c, res_d = int(a.solution_value()), int(b.solution_value()),\
                                         int(c.solution_value()), int(d.solution_value())
            ret = MobiusTransform(
                np.array([[res_a, res_b], [res_c, res_d]], dtype=object))
            ret.normalize()
            return ret
    else:
        return None
def main():
    # Create the linear solver with the GLOP backend.
    solver = Solver('simple_lp_program', Solver.GLOP_LINEAR_PROGRAMMING)

    # Create the variables x and y.
    x = solver.NumVar(0, 1, 'x')
    y = solver.NumVar(0, 2, 'y')

    print('Number of variables =', solver.NumVariables())

    # Create a linear constraint, 0 <= x + y <= 2.
    ct = solver.Constraint(0, 2, 'ct')
    ct.SetCoefficient(x, 1)
    ct.SetCoefficient(y, 1)

    print('Number of constraints =', solver.NumConstraints())

    # Create the objective function, 3 * x + y.
    objective = solver.Objective()
    objective.SetCoefficient(x, 3)
    objective.SetCoefficient(y, 1)
    objective.SetMaximization()

    solver.Solve()

    print('Solution:')
    print('Objective value =', objective.Value())
    print('x =', x.solution_value())
    print('y =', y.solution_value())
示例#3
0
 def _declare_variable(self, solver: pywraplp.Solver, nth_cycle: int,
                       nth_index: int) -> None:
     return solver.NumVar(
         MIN_N_PHASES_FOR_SUSTAIN,
         MIN_N_PHASES_FOR_SUSTAIN * MAX_N_MIN_PHASES_FOR_SUSTAIN,
         self._get_variable_name(nth_cycle, nth_index),
     )
示例#4
0
    def _add_stock_variables(num_types: int, num_time_periods: int, solver: Solver) \
            -> Dict[V, Variable]:
        """Create stock variables.

         A stock variable $s^t_p$ is a non-negative real variable which represents the number of
         items of type $t$ on stock in time period $p$.

        :param num_types: the number of considered types
        :param num_time_periods: the number of considered time periods
        :param solver: the underlying solver for which to built the variables
        :return: A dictionary mapping each stock variable to its solver variable
        """
        stock_vars = dict()
        for (item_type, time_period) in product(range(num_types),
                                                range(-1, num_time_periods)):
            stock_vars[V(type=item_type, period=time_period)] = \
                solver.NumVar(lb=0., ub=solver.infinity(), name=f's_{item_type}_{time_period}')
        module_logger.info(f'Created {len(stock_vars)} stock variables.')
        return stock_vars
示例#5
0
def _set_coefficients(solver: pywraplp.Solver, objective_or_constraint,
                      coefficient_part: str, line_nr: int, var_names: set):

    # Strip the coefficient whitespace
    remainder = coefficient_part.strip()
    if len(remainder) == 0:
        raise ValueError("No variables present in equation on line %d." %
                         line_nr)

    # All variables found
    var_names_found = set()

    running_constant_sum = 0.0
    had_at_least_one_variable = False
    while len(remainder) != 0:

        # Combination sign
        coefficient = 1.0
        combination_sign_match = re.search(r"^[-+]", remainder)
        if combination_sign_match is not None:
            if combination_sign_match.group() == "-":
                coefficient = -1.0
            remainder = remainder[1:].strip()

        # Real sign
        sign_match = re.search(r"^[-+]", remainder)
        if sign_match is not None:
            if sign_match.group() == "-":
                coefficient = coefficient * -1.0
            remainder = remainder[
                1:]  # There is no strip() here, as it must be directly in front of the mantissa

        # Mantissa and exponent
        mantissa_exp_match = re.search(r"^(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?",
                                       remainder)
        whitespace_after = False
        if mantissa_exp_match is not None:
            coefficient = coefficient * float(mantissa_exp_match.group())
            remainder = remainder[mantissa_exp_match.span()[1]:]
            stripped_remainder = remainder.strip()
            if len(remainder) != len(stripped_remainder):
                whitespace_after = True
            remainder = stripped_remainder

        # Variable name
        var_name_match = re.search(_REGEXP_SINGLE_VAR_NAME_START, remainder)
        if var_name_match is not None:

            # It must have had at least one variable
            had_at_least_one_variable = True

            # Retrieve clean variable name
            clean_var = var_name_match.group()
            var_names.add(clean_var)
            if clean_var in var_names_found:
                raise ValueError(
                    "Variable \"%s\" found more than once on line %d." %
                    (clean_var, line_nr))
            var_names_found.add(clean_var)
            solver_var = solver.LookupVariable(clean_var)
            if solver_var is None:
                solver_var = solver.NumVar(-solver.infinity(),
                                           solver.infinity(), clean_var)

            # Set coefficient
            objective_or_constraint.SetCoefficient(solver_var, coefficient)

            # Strip what we matched
            remainder = remainder[var_name_match.span()[1]:]
            stripped_remainder = remainder.strip()
            whitespace_after = False
            if len(remainder) != len(stripped_remainder):
                whitespace_after = True
            remainder = stripped_remainder

        elif mantissa_exp_match is None:
            raise ValueError(
                "Cannot process remainder coefficients of \"%s\" on line %d." %
                (remainder, line_nr))

        else:
            running_constant_sum += coefficient

        # At the end of each element there either:
        # (a) Must be whitespace (e.g., x1 x2 <= 10)
        # (b) The next combination sign (e.g., x1+x2 <= 10)
        # (c) Or it was the last one, as such remainder is empty (e.g., x1 <= 10)
        if len(remainder) != 0 and not whitespace_after and remainder[
                0:1] != "-" and remainder[0:1] != "+":
            raise ValueError(
                "Unexpected next character \"%s\" on line %d (expected whitespace or "
                "combination sign character)." % (remainder[0:1], line_nr))

    # There must have been at least one variable
    if not had_at_least_one_variable:
        raise ValueError(
            "Not a single variable present in the coefficients on line %d." %
            line_nr)

    return running_constant_sum