Example #1
0
def solve_tsp_by_mip(tsp_matrix):
    start = time()
    matrix_of_distances = get_matrix_of_distances(tsp_matrix)
    length = len(tsp_matrix)

    model = Model(solver_name='gurobi')
    model.verbose = 1

    x = [[model.add_var(var_type=BINARY) for j in range(length)]
         for i in range(length)]

    y = [model.add_var() for i in range(length)]

    model.objective = xsum(matrix_of_distances[i][j] * x[i][j]
                           for j in range(length) for i in range(length))

    for i in range(length):
        model += xsum(x[j][i] for j in range(length) if j != i) == 1
        model += xsum(x[i][j] for j in range(length) if j != i) == 1

    for i in range(1, length):
        for j in [x for x in range(1, length) if x != i]:
            model += y[i] - (length + 1) * x[i][j] >= y[j] - length

    model.optimize(max_seconds=300)

    arcs = [(i, j) for i in range(length) for j in range(length)
            if x[i][j].x >= 0.99]

    best_distance = calculate_total_dist_by_arcs(matrix_of_distances, arcs)
    time_diff = time() - start
    return arcs, time_diff, best_distance
Example #2
0
def test_queens(solver: str):
    """MIP model n-queens"""
    n = 50
    announce_test("n-Queens", solver)

    queens = Model('queens', MAXIMIZE, solver_name=solver)
    queens.verbose = 0

    x = [[
        queens.add_var('x({},{})'.format(i, j), var_type=BINARY)
        for j in range(n)
    ] for i in range(n)]

    # one per row
    for i in range(n):
        queens += xsum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i)

    # one per column
    for j in range(n):
        queens += xsum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j)

    # diagonal \
    for p, k in enumerate(range(2 - n, n - 2 + 1)):
        queens += xsum(x[i][j] for i in range(n) for j in range(n)
                       if i - j == k) <= 1, 'diag1({})'.format(p)

    # diagonal /
    for p, k in enumerate(range(3, n + n)):
        queens += xsum(x[i][j] for i in range(n) for j in range(n)
                       if i + j == k) <= 1, 'diag2({})'.format(p)

    queens.optimize()

    check_result("model status", queens.status == OptimizationStatus.OPTIMAL)

    # querying problem variables and checking opt results
    total_queens = 0
    for v in queens.vars:
        # basic integrality test
        assert v.x <= 0.0001 or v.x >= 0.9999
        total_queens += v.x

    # solution feasibility
    rows_with_queens = 0
    for i in range(n):
        if abs(sum(x[i][j].x for j in range(n)) - 1) <= 0.001:
            rows_with_queens += 1

    check_result("feasible solution",
                 abs(total_queens - n) <= 0.001 and rows_with_queens == n)
    print('')
Example #3
0
def solve_tsp_by_mip_with_sub_cycles_2(tsp_matrix):
    start = time()
    matrix_of_distances = get_matrix_of_distances(tsp_matrix)
    total_length = len(tsp_matrix)
    best_distance = sys.float_info.max

    found_cycles = []
    arcs = [(i, i + 1) for i in range(total_length - 1)]

    iteration = 0

    model = Model(solver_name='gurobi')
    model.verbose = 0

    x = [[model.add_var(var_type=BINARY) for j in range(total_length)]
         for i in range(total_length)]

    y = [model.add_var() for i in range(total_length)]

    model.objective = xsum(matrix_of_distances[i][j] * x[i][j]
                           for j in range(total_length)
                           for i in range(total_length))

    for i in range(total_length):
        model += (xsum(x[i][j] for j in range(0, i)) +
                  xsum(x[j][i] for j in range(i + 1, total_length))) == 2

    while len(found_cycles) != 1:
        model.optimize(max_seconds=300)

        arcs = [(i, j) for i in range(total_length)
                for j in range(total_length) if x[i][j].x >= 0.99]
        best_distance = calculate_total_dist_by_arcs(matrix_of_distances, arcs)

        found_cycles = get_cycle(arcs)

        for cycle in found_cycles:
            points = {}
            for arc in cycle:
                points = {*points, arc[0]}
                points = {*points, arc[1]}
            cycle_len = len(cycle)
            model += xsum(x[arc[0]][arc[1]]
                          for arc in permutations(points, 2)) <= cycle_len - 1

        # plot_connected_tsp_points_from_arcs(tsp_matrix, arcs, '../images/mip_xql662/{}'.format(iteration))
        print(iteration)
        iteration += 1

    time_diff = time() - start
    return arcs, time_diff, best_distance
Example #4
0
def test_tsp_mipstart(solver: str):
    """tsp related tests"""
    announce_test("TSP - MIPStart", solver)
    N = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    n = len(N)
    i0 = N[0]

    A = {
        ('a', 'd'): 56,
        ('d', 'a'): 67,
        ('a', 'b'): 49,
        ('b', 'a'): 50,
        ('d', 'b'): 39,
        ('b', 'd'): 37,
        ('c', 'f'): 35,
        ('f', 'c'): 35,
        ('g', 'b'): 35,
        ('b', 'g'): 25,
        ('a', 'c'): 80,
        ('c', 'a'): 99,
        ('e', 'f'): 20,
        ('f', 'e'): 20,
        ('g', 'e'): 38,
        ('e', 'g'): 49,
        ('g', 'f'): 37,
        ('f', 'g'): 32,
        ('b', 'e'): 21,
        ('e', 'b'): 30,
        ('a', 'g'): 47,
        ('g', 'a'): 68,
        ('d', 'c'): 37,
        ('c', 'd'): 52,
        ('d', 'e'): 15,
        ('e', 'd'): 20
    }

    # input and output arcs per node
    Aout = {n: [a for a in A if a[0] == n] for n in N}
    Ain = {n: [a for a in A if a[1] == n] for n in N}
    m = Model(solver_name=solver)
    m.verbose = 0

    x = {
        a: m.add_var(name='x({},{})'.format(a[0], a[1]), var_type=BINARY)
        for a in A
    }

    m.objective = xsum(c * x[a] for a, c in A.items())

    for i in N:
        m += xsum(x[a] for a in Aout[i]) == 1, 'out({})'.format(i)
        m += xsum(x[a] for a in Ain[i]) == 1, 'in({})'.format(i)

    # continuous variable to prevent subtours: each
    # city will have a different "identifier" in the planned route
    y = {i: m.add_var(name='y({})'.format(i), lb=0.0) for i in N}

    # subtour elimination
    for (i, j) in A:
        if i0 not in [i, j]:
            m.add_constr(y[i] - (n + 1) * x[(i, j)] >= y[j] - n)

    route = ['a', 'g', 'f', 'c', 'd', 'e', 'b', 'a']
    m.start = [(x[route[i - 1], route[i]], 1.0) for i in range(1, len(route))]
    m.optimize()

    check_result("mip model status", m.status == OptimizationStatus.OPTIMAL)
    check_result("mip model objective",
                 (abs(m.objective_value - 262)) <= 0.0001)
    print('')