예제 #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
예제 #2
0
    def _declare_constraint(
        solver: pywraplp.Solver,
        group: "Group",
        variables: typing.Tuple[typing.Tuple[pywraplp.Variable]],
    ) -> None:
        higher_groups = group.get_simultaneous_groups_of_higher_cycle()
        if higher_groups:
            # fixed duration of group
            summed_active_transitions_of_group = Group._sum_active_transitions_of_group(
                group, higher_groups)

            # fixed duration of higher groups
            summed_transitions_of_higher_groups = sum(
                Group._calculate_duration_of_n_phases(higher_group,
                                                      higher_group.attack)
                for higher_group in higher_groups)
            summed_transitions_of_higher_groups += Group._calculate_duration_of_n_phases(
                higher_groups[-1], higher_groups[-1].release)
            difference_of_duration = (summed_active_transitions_of_group -
                                      summed_transitions_of_higher_groups)
            constraint = sum(
                Group._calculate_duration_of_n_phases(higher_group, var)
                for var, higher_group in zip(variables[1], higher_groups))
            constraint = constraint - (Group._calculate_duration_of_n_phases(
                group, variables[0][0]))
            solver.Add(constraint == difference_of_duration)