示例#1
0
def solve_hidato(puzzle, index):
    """Solve the given hidato table."""
    # Create the model.
    model = cp_model.CpModel()

    r = len(puzzle)
    c = len(puzzle[0])
    if not visualization.RunFromIPython():
        print('')
        print('----- Solving problem %i -----' % index)
        print('')
        print(('Initial game (%i x %i)' % (r, c)))
        print_matrix(puzzle)

    #
    # declare variables
    #
    positions = [
        model.NewIntVar(0, r * c - 1, 'p[%i]' % i) for i in range(r * c)
    ]

    #
    # constraints
    #
    model.AddAllDifferent(positions)

    #
    # Fill in the clues
    #
    for i in range(r):
        for j in range(c):
            if puzzle[i][j] > 0:
                model.Add(positions[puzzle[i][j] - 1] == i * c + j)

    # Consecutive numbers much touch each other in the grid.
    # We use an allowed assignment constraint to model it.
    close_tuples = build_pairs(r, c)
    for k in range(0, r * c - 1):
        model.AddAllowedAssignments([positions[k], positions[k + 1]],
                                    close_tuples)

    #
    # solution and search
    #

    solver = cp_model.CpSolver()
    status = solver.Solve(model)

    if status == cp_model.OPTIMAL:
        if visualization.RunFromIPython():
            output = visualization.SvgWrapper(10, r, 40.0)
            for i, var in enumerate(positions):
                val = solver.Value(var)
                x = val % c
                y = val // c
                color = 'white' if puzzle[y][x] == 0 else 'lightgreen'
                output.AddRectangle(x, r - y - 1, 1, 1, color, 'black',
                                    str(i + 1))

            output.AddTitle('Puzzle %i solved in %f s' %
                            (index, solver.WallTime()))
            output.Display()
        else:
            print_solution(
                [solver.Value(x) for x in positions],
                r,
                c,
            )
            print('Statistics')
            print('  - conflicts : %i' % solver.NumConflicts())
            print('  - branches  : %i' % solver.NumBranches())
            print('  - wall time : %f s' % solver.WallTime())
示例#2
0
def main():
    # Creates the solver.
    model = cp_model.CpModel()

    machines_count = 6
    jobs_count = 6
    all_machines = range(0, machines_count)
    all_jobs = range(0, jobs_count)

    durations = [[1, 3, 6, 7, 3, 6], [8, 5, 10, 10, 10, 4], [5, 4, 8, 9, 1, 7],
                 [5, 5, 5, 3, 8, 9], [9, 3, 5, 4, 3, 1], [3, 3, 9, 10, 4, 1]]

    machines = [[2, 0, 1, 3, 5, 4], [1, 2, 4, 5, 0, 3], [2, 3, 5, 0, 1, 4],
                [1, 0, 2, 3, 4, 5], [2, 1, 4, 5, 0, 3], [1, 3, 5, 0, 4, 2]]

    # Computes horizon dynamically.
    horizon = sum([sum(durations[i]) for i in all_jobs])

    # Creates jobs.
    all_tasks = {}
    for i in all_jobs:
        for j in all_machines:
            start = model.NewIntVar(0, horizon, 'start_%i_%i' % (i, j))
            duration = durations[i][j]
            end = model.NewIntVar(0, horizon, 'end_%i_%i' % (i, j))
            interval = model.NewIntervalVar(start, duration, end,
                                            'interval_%i_%i' % (i, j))
            all_tasks[(i, j)] = (start, end, interval)

    # Create disjuctive constraints.
    machine_to_jobs = {}
    for i in all_machines:
        machines_jobs = []
        for j in all_jobs:
            for k in all_machines:
                if machines[j][k] == i:
                    machines_jobs.append(all_tasks[(j, k)][2])
        machine_to_jobs[i] = machines_jobs
        model.AddNoOverlap(machines_jobs)

    # Precedences inside a job.
    for i in all_jobs:
        for j in range(0, machines_count - 1):
            model.Add(all_tasks[(i, j + 1)][0] >= all_tasks[(i, j)][1])

    # Makespan objective.
    obj_var = model.NewIntVar(0, horizon, 'makespan')
    model.AddMaxEquality(
        obj_var, [all_tasks[(i, machines_count - 1)][1] for i in all_jobs])
    model.Minimize(obj_var)

    # Solve model.
    solver = cp_model.CpSolver()
    response = solver.Solve(model)

    # Output solution.
    if visualization.RunFromIPython():
        starts = [[solver.Value(all_tasks[(i, j)][0]) for j in all_machines]
                  for i in all_jobs]
        visualization.DisplayJobshop(starts, durations, machines, 'FT06')
    else:
        print('Optimal makespan: %i' % solver.ObjectiveValue())
def main():
    """Solves the gate scheduling problem."""
    model = cp_model.CpModel()

    jobs = [[3, 3], [2, 5], [1, 3], [3, 7], [7, 3], [2, 2], [2, 2], [5, 5],
            [10, 2], [4, 3], [2, 6], [1, 2], [6, 8], [4, 5], [3, 7]]

    max_length = 10

    horizon = sum(t[0] for t in jobs)
    num_jobs = len(jobs)
    all_jobs = range(num_jobs)

    intervals = []
    intervals0 = []
    intervals1 = []
    performed = []
    starts = []
    ends = []
    demands = []

    for i in all_jobs:
        # Create main interval.
        start = model.NewIntVar(0, horizon, 'start_%i' % i)
        duration = jobs[i][0]
        end = model.NewIntVar(0, horizon, 'end_%i' % i)
        interval = model.NewIntervalVar(start, duration, end,
                                        'interval_%i' % i)
        starts.append(start)
        intervals.append(interval)
        ends.append(end)
        demands.append(jobs[i][1])

        performed_on_m0 = model.NewBoolVar('perform_%i_on_m0' % i)
        performed.append(performed_on_m0)

        # Create an optional copy of interval to be executed on machine 0.
        start0 = model.NewIntVar(0, horizon, 'start_%i_on_m0' % i)
        end0 = model.NewIntVar(0, horizon, 'end_%i_on_m0' % i)
        interval0 = model.NewOptionalIntervalVar(start0, duration, end0,
                                                 performed_on_m0,
                                                 'interval_%i_on_m0' % i)
        intervals0.append(interval0)

        # Create an optional copy of interval to be executed on machine 1.
        start1 = model.NewIntVar(0, horizon, 'start_%i_on_m1' % i)
        end1 = model.NewIntVar(0, horizon, 'end_%i_on_m1' % i)
        interval1 = model.NewOptionalIntervalVar(start1, duration, end1,
                                                 performed_on_m0.Not(),
                                                 'interval_%i_on_m1' % i)
        intervals1.append(interval1)

        # We only propagate the constraint if the tasks is performed on the machine.
        model.Add(start0 == start).OnlyEnforceIf(performed_on_m0)
        model.Add(start1 == start).OnlyEnforceIf(performed_on_m0.Not())

    # Max Length constraint (modeled as a cumulative)
    model.AddCumulative(intervals, demands, max_length)

    # Choose which machine to perform the jobs on.
    model.AddNoOverlap(intervals0)
    model.AddNoOverlap(intervals1)

    # Objective variable.
    makespan = model.NewIntVar(0, horizon, 'makespan')
    model.AddMaxEquality(makespan, ends)
    model.Minimize(makespan)

    # Symmetry breaking.
    model.Add(performed[0] == 0)

    # Solve model.
    solver = cp_model.CpSolver()
    solver.Solve(model)

    # Output solution.
    if visualization.RunFromIPython():
        output = visualization.SvgWrapper(solver.ObjectiveValue(), max_length,
                                          40.0)
        output.AddTitle('Makespan = %i' % solver.ObjectiveValue())
        color_manager = visualization.ColorManager()
        color_manager.SeedRandomColor(0)

        for i in all_jobs:
            performed_machine = 1 - solver.Value(performed[i])
            start = solver.Value(starts[i])
            d_x = jobs[i][0]
            d_y = jobs[i][1]
            s_y = performed_machine * (max_length - d_y)
            output.AddRectangle(start, s_y, d_x, d_y,
                                color_manager.RandomColor(), 'black',
                                'j%i' % i)

        output.AddXScale()
        output.AddYScale()
        output.Display()
    else:
        print('Solution')
        print('  - makespan = %i' % solver.ObjectiveValue())
        for i in all_jobs:
            performed_machine = 1 - solver.Value(performed[i])
            start = solver.Value(starts[i])
            print('  - Job %i starts at %i on machine %i' %
                  (i, start, performed_machine))
        print('Statistics')
        print('  - conflicts : %i' % solver.NumConflicts())
        print('  - branches  : %i' % solver.NumBranches())
        print('  - wall time : %f ms' % solver.WallTime())
示例#4
0
def jobshop_ft06():
    """Solves the ft06 jobshop."""
    # Creates the solver.
    model = cp_model.CpModel()

    machines_count = 6
    jobs_count = 6
    all_machines = range(0, machines_count)
    all_jobs = range(0, jobs_count)

    durations = [[1, 3, 6, 7, 3, 6], [8, 5, 10, 10, 10, 4], [5, 4, 8, 9, 1, 7],
                 [5, 5, 5, 3, 8, 9], [9, 3, 5, 4, 3, 1], [3, 3, 9, 10, 4, 1]]

    machines = [[2, 0, 1, 3, 5, 4], [1, 2, 4, 5, 0, 3], [2, 3, 5, 0, 1, 4],
                [1, 0, 2, 3, 4, 5], [2, 1, 4, 5, 0, 3], [1, 3, 5, 0, 4, 2]]

    # Computes horizon dynamically.
    horizon = sum([sum(durations[i]) for i in all_jobs])

    task_type = collections.namedtuple('task_type', 'start end interval')

    # Creates jobs.
    all_tasks = {}
    for i in all_jobs:
        for j in all_machines:
            start_var = model.NewIntVar(0, horizon, 'start_%i_%i' % (i, j))
            duration = durations[i][j]
            end_var = model.NewIntVar(0, horizon, 'end_%i_%i' % (i, j))
            interval_var = model.NewIntervalVar(start_var, duration, end_var,
                                                'interval_%i_%i' % (i, j))
            all_tasks[(i, j)] = task_type(start=start_var,
                                          end=end_var,
                                          interval=interval_var)

    # Create disjuctive constraints.
    machine_to_jobs = {}
    for i in all_machines:
        machines_jobs = []
        for j in all_jobs:
            for k in all_machines:
                if machines[j][k] == i:
                    machines_jobs.append(all_tasks[(j, k)].interval)
        machine_to_jobs[i] = machines_jobs
        model.AddNoOverlap(machines_jobs)

    # Precedences inside a job.
    for i in all_jobs:
        for j in range(0, machines_count - 1):
            model.Add(all_tasks[(i, j + 1)].start >= all_tasks[(i, j)].end)

    # Makespan objective.
    obj_var = model.NewIntVar(0, horizon, 'makespan')
    model.AddMaxEquality(
        obj_var, [all_tasks[(i, machines_count - 1)].end for i in all_jobs])
    model.Minimize(obj_var)

    # Solve model.
    solver = cp_model.CpSolver()
    solver.parameters.log_search_progress = True
    status = solver.Solve(model)

    # Output solution.
    if status == cp_model.OPTIMAL:
        if visualization.RunFromIPython():
            starts = [[
                solver.Value(all_tasks[(i, j)][0]) for j in all_machines
            ] for i in all_jobs]
            visualization.DisplayJobshop(starts, durations, machines, 'FT06')
        else:
            print('Optimal makespan: %i' % solver.ObjectiveValue())
示例#5
0
model.AddNoOverlap(intervals1)

# Objective variable.
makespan = model.NewIntVar(0, horizon, 'makespan')
model.AddMaxEquality(makespan, ends)
model.Minimize(makespan)

# Symmetry breaking.
model.Add(performed[0] == 0)

# Solve model.
solver = cp_model.CpSolver()
solver.Solve(model)

# Output solution.
if visualization.RunFromIPython():
    output = visualization.SvgWrapper(solver.ObjectiveValue(), max_length,
                                      40.0)
    output.AddTitle('Makespan = %i' % solver.ObjectiveValue())
    color_manager = visualization.ColorManager()
    color_manager.SeedRandomColor(0)

    for i in all_jobs:
        performed_machine = 1 - solver.Value(performed[i])
        start = solver.Value(starts[i])
        dx = jobs[i][0]
        dy = jobs[i][1]
        sy = performed_machine * (max_length - dy)
        output.AddRectangle(start, sy, dx, dy, color_manager.RandomColor(),
                            'black', 'j%i' % i)