# get nr of constraints in model nrConstraints = model.num_rows print("The mode consists of " + str(nrVariables) + " decision variables and " + str(nrConstraints) + " constraints.") print("Optimization process started.") # get time limit in seconds for optimization timeInSeconds = optimization_parameters.loc["timeInSeconds", "Value"] # get mip gap mipGap = optimization_parameters.loc["mipGap", "Value"] # if time limit was given use this time limit else default value: +inf if not pd.isna(timeInSeconds): model.max_seconds = timeInSeconds print("Maximal solution time: " + str(timeInSeconds) + " seconds") # if mip gap was given use this gap else default value: 1e-4 if not pd.isna(mipGap): model.max_mip_gap = mipGap print("MIP gap set to " + str(mipGap * 100) + "%") # start optimizing status = model.optimize() solved = False # optimal solution found if status == OptimizationStatus.OPTIMAL: if model.gap < 1e-4:
def test_tsp_cuts(solver: str): """tsp related tests""" 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) m.cuts_generator = SubTourCutGenerator() # tiny model, should be enough to find the optimal m.max_seconds = 10 m.max_nodes = 100 m.max_solutions = 1000 m.optimize() assert m.status == OptimizationStatus.OPTIMAL # "mip model status" assert abs(m.objective_value - 262) <= TOL # "mip model objective"
L = [cost for i in range(50)] sl, cur_cost, best = seq.copy(), cost, cost for it in range(5000000): (i, j) = rnd.randint(1, len(sl) - 2), rnd.randint(1, len(sl) - 2) dlt = delta(c, sl, i, j) if cur_cost + dlt <= L[it % len(L)]: sl[i], sl[j], cur_cost = sl[j], sl[i], cur_cost + dlt if cur_cost < best: seq, best = sl.copy(), cur_cost L[it % len(L)] = cur_cost print('improved cost %g' % best) model.start = [(x[seq[i]][seq[i + 1]], 1) for i in range(len(seq) - 1)] model.max_seconds = timeLimit model.threads = threads model.optimize() end = time() print(model.status) print(model.solver_name) objv = 1e20 gap = 1e20 n_nodes = 0 if model.status in [OptimizationStatus.OPTIMAL, OptimizationStatus.FEASIBLE]: out.write('route with total distance %g found: 0' % (model.objective_value))