### Providing Initial Feasible Solutions Source: https://github.com/coin-or/python-mip/blob/master/docs/custom.md This example shows how to provide an initial feasible solution to the MIP solver using the `start` property. It involves creating a list of (variable, value) pairs, which can help improve pruning and local search heuristics. ```python from random import shuffle S=[i for i in range(n)] shuffle(S) model.start = [(x[S[k-1]][S[k]], 1.0) for k in range(n)] ``` -------------------------------- ### TSP Warm-Start Example Source: https://context7.com/coin-or/python-mip/llms.txt Demonstrates how to provide a greedy nearest-neighbor tour as a warm start for the Traveling Salesperson Problem (TSP) to potentially speed up optimization. ```python n = 10 import random random.seed(42) c = [[random.randint(1, 100) if i != j else 0 for j in range(n)] for i in range(n)] V = set(range(n)) m = Model() x = [[m.add_var(var_type=BINARY) for j in V] for i in V] y = [m.add_var() for i in V] m.objective = minimize(xsum(c[i][j] * x[i][j] for i in V for j in V)) for i in V: m += xsum(x[i][j] for j in V - {i}) == 1 m += xsum(x[j][i] for j in V - {i}) == 1 # Provide a greedy nearest-neighbor tour as a warm start route = list(range(n)) shuffle(route) m.start = [(x[route[k - 1]][route[k]], 1.0) for k in range(n)] m.optimize(max_seconds=30) print(f"Tour cost: {m.objective_value}") ``` -------------------------------- ### Install Python-MIP for the current user Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md If global installation fails due to permissions, use this command to install Python-MIP for the current user only. ```sh pip install mip --user ``` -------------------------------- ### Plant Location Model Setup Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md Initializes data structures for a plant location problem. This setup is part of a larger model that uses Special Ordered Sets (SOS) to handle non-linear costs and capacity constraints. ```python C = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # position of clients pc = { 1: (94, 10), 2: (57, 26), 3: (74, 44), 4: (27, 51), 5: (78, 30), 6: (23, 30), 7: (20, 72), 8: (3, 27), 9: (5, 39), 10: (51, 1), } ``` -------------------------------- ### Install Python-MIP with Pypy Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Install Python-MIP as a package for the Pypy interpreter. The `--user` flag may also be necessary. ```sh pypy3 -m pip install mip ``` -------------------------------- ### Install Python-MIP using pip Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Use this command to install the Python-MIP package. Ensure you have Python 3.5 or newer installed. ```sh pip install mip ``` -------------------------------- ### Install CBC build dependencies on Ubuntu Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Installs the necessary development tools and libraries required to build CBC from source on Ubuntu-based systems. ```sh # install dependencies to build sudo apt-get install gcc g++ gfortran libgfortran-9-dev liblapack-dev libamd2 libcholmod3 libmetis-dev libsuitesparse-dev libnauty2-dev git ``` -------------------------------- ### Install mip with HiGHS support Source: https://github.com/coin-or/python-mip/blob/master/RELEASE-ANNOUNCEMENT.md Install python-mip with the HiGHS solver backend. This installs the 'mip' package and its optional 'highs' dependency. ```bash pip install mip[highs] ``` -------------------------------- ### Create and Optimize a MIP Model Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Demonstrates the basic workflow for creating a MIP model, adding variables and constraints, setting the objective function, and optimizing the model. Ensure the 'mip' library is installed and a solver like CBC is available. ```python >>> from mip import Model, MAXIMIZE, CBC, INTEGER, OptimizationStatus >>> model = Model(sense=MAXIMIZE, solver_name=CBC) >>> x = model.add_var(name='x', var_type=INTEGER, lb=0, ub=10) >>> y = model.add_var(name='y', var_type=INTEGER, lb=0, ub=10) >>> model += x + y <= 10 >>> model.objective = x + y >>> status = model.optimize(max_seconds=2) >>> status == OptimizationStatus.OPTIMAL True ``` -------------------------------- ### Bandwidth Multicoloring Problem (BMCP) Solver Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md Formulates and solves the Bandwidth Multicoloring Problem using a mixed-integer programming approach. This example sets up the problem with demands and distance constraints. ```python from itertools import product from mip import Model, xsum, minimize, BINARY # number of channels per node r = [3, 5, 8, 3, 6, 5, 7, 3] # distance between channels in the same node (i, i) and in adjacent nodes # 0 1 2 3 4 5 6 7 d = [[3, 2, 0, 0, 2, 2, 0, 0], # 0 [2, 3, 2, 0, 0, 2, 2, 0], # 1 [0, 2, 3, 0, 0, 0, 3, 0], # 2 [0, 0, 0, 3, 2, 0, 0, 2], # 3 [2, 0, 0, 2, 3, 2, 0, 0], # 4 [2, 2, 0, 0, 2, 3, 2, 0], # 5 [0, 2, 2, 0, 0, 2, 3, 0], # 6 [0, 0, 0, 2, 0, 0, 0, 3]] # 7 N = range(len(r)) # in complete applications this upper bound should be obtained from a feasible ``` -------------------------------- ### Upgrade MiP Package with HiGHS Support Source: https://github.com/coin-or/python-mip/blob/master/RELEASE-ANNOUNCEMENT.md Install or upgrade MiP with HiGHS solver support using this command. ```bash pip install --upgrade "mip[highs]" ``` -------------------------------- ### Build Dockerfile for ARM Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md This Dockerfile sets up an Alpine Linux environment to build CBC for Python-MIP on an ARMv6 platform. It installs necessary build tools and dependencies, fetches and builds CBC, and installs Python dependencies. ```dockerfile # syntax=docker/dockerfile:1 FROM arm32v6/python:3.7-alpine3.15 AS builder RUN apk add --no-cache \ bash \ gcc \ gfortran \ git \ g++ \ libffi-dev \ libgfortran \ lapack-dev \ make \ patch RUN wget https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew RUN chmod u+x coinbrew RUN ./coinbrew fetch Cbc@master RUN ./coinbrew build Cbc@master --prefix=/home/haroldo/prog/ --tests=none --enable-cbc-parallel --enable-relocatable COPY requirements.txt requirements.txt RUN mkdir /pip-install && pip3 install --prefix=/pip-install -r requirements.txt FROM arm32v6/python:3.7-alpine3.15 RUN apk add --no-cache \ libffi-dev \ libgfortran \ lapack-dev \ libstdc++6 COPY --from=builder /home/haroldo/prog /home/haroldo/prog/ COPY --from=builder /pip-install /usr/local COPY . . ENV PMIP_CBC_LIBRARY="/home/haroldo/prog/lib/libCbc.so" ENV PATH=$PATH:/home/haroldo/prog/bin RUN chmod u+x ./entrypoint.sh ENTRYPOINT ["./entrypoint.sh"] ``` -------------------------------- ### Create Model with Custom Settings Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Create a Model object with a specified objective sense (e.g., MAXIMIZE) and solver (e.g., CBC). Gurobi is used automatically if installed and configured. ```python m = Model(sense=MAXIMIZE, solver_name=CBC) # use GRB for Gurobi ``` -------------------------------- ### Job Shop Scheduling Problem Formulation and Optimization Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md Defines constraints for a job shop scheduling problem and optimizes the model. Prints the completion time and start times for each task on each machine. ```python model += -x[j][i] + x[k][i] - M*y[j][k][i] >= times[j][i] - M for j in range(n): model += c - x[j][machines[j][m - 1]] >= times[j][machines[j][m - 1]] model.optimize() print("Completion time: ", c.x) for (j, i) in product(range(n), range(m)): print("task %d starts on machine %d at time %g " % (j+1, i+1, x[j][i].x)) ``` -------------------------------- ### Custom Cutting Plane Separation Routine Source: https://github.com/coin-or/python-mip/blob/master/docs/custom.md Implements a custom separation routine for cutting planes. This example iteratively solves the LP relaxation and adds violated inequalities found by a minimum cut algorithm until no more violated inequalities are detected. ```python m += xsum(x[a] for a in Ain[n]) == 1, "in({})".format(n) newConstraints = True while newConstraints: m.optimize(relax=True) print("status: {} objective value : {}".format(m.status, m.objective_value)) G = DiGraph() for a in A: G.add_edge(a[0], a[1], capacity=x[a].x) newConstraints = False for (n1, n2) in [(i, j) for (i, j) in product(N, N) if i != j]: cut_value, (S, NS) = minimum_cut(G, n1, n2) if cut_value <= 0.99: m += (xsum(x[a] for a in A if (a[0] in S and a[1] in S)) <= len(S) - 1) newConstraints = True ``` -------------------------------- ### Provide Initial Feasible Solution (MIPStart) Source: https://context7.com/coin-or/python-mip/llms.txt Use `Model.start` to warm-start the solver with a known feasible solution, which can significantly reduce solve time. Pass a list of `(Var, value)` pairs; only non-zero integer/binary variables need to be specified. ```python from mip import Model, xsum, minimize, BINARY from random import shuffle ``` -------------------------------- ### Model.start Source: https://context7.com/coin-or/python-mip/llms.txt Provide an initial feasible solution (MIPStart) to warm-start the solver, potentially reducing solve time. Accepts a list of `(Var, value)` pairs. ```APIDOC ## `Model.start` — Provide an initial feasible solution (MIPStart) Warm-starts the branch-and-cut solver with a known feasible solution, often dramatically reducing solve time. Pass a list of `(Var, value)` pairs; only non-zero integer/binary variables need to be specified. ```python from mip import Model, xsum, minimize, BINARY from random import shuffle ``` ``` -------------------------------- ### Download and build CBC with coinbrew Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Uses coinbrew to fetch and compile the CBC solver and its dependencies. Customize the prefix and build options as needed. ```sh # directory to download and compile CBC mkdir -p ~/build ; cd ~/build # download latest version of coinbrew wget -nH https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew # download CBC and its dependencies with coinbrew bash coinbrew fetch Cbc@master --no-prompt # build, replace prefix with your install directory, add --enable-debug if necessary bash coinbrew build Cbc@master --no-prompt --prefix=/home/haroldo/prog/ --tests=none --enable-cbc-parallel --enable-relocatable ``` -------------------------------- ### Create and Configure a MIP Model Source: https://context7.com/coin-or/python-mip/llms.txt Instantiate the Model class to create a new MIP model. The solver is automatically selected, but can be specified. The sense defaults to MINIMIZE and can be set to MAXIMIZE. ```python from mip import Model, MAXIMIZE, MINIMIZE, CBC, GRB # Minimization model using CBC (default) m_min = Model() # Maximization model using Gurobi m_max = Model(name="my_problem", sense=MAXIMIZE, solver_name=GRB) # Force CBC even if Gurobi is installed m_cbc = Model(sense=MINIMIZE, solver_name=CBC) print(m_min.sense) # 'MIN' print(m_max.sense) # 'MAX' ``` -------------------------------- ### Add a Simple Constraint Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Add a linear constraint to the model using the += operator. This example adds a less-than-or-equal-to constraint. ```python m += x + y <= 10 ``` -------------------------------- ### Model Methods Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Methods available for the MIP model object, including translating references, validating MIP starts, searching variables by name, and writing model data. ```APIDOC ## Model Methods ### translate(ref) * **Description:** Translates references of variables/containers of variables from another model to this model. Can be used to translate references of variables in the original model to references of variables in the pre-processed model. * **Parameters:** * **ref** (any) - Reference to translate. * **Return type:** Union[List[Any], Dict[Any, Any], [Var](#mip.Var)] ### validate_mip_start() * **Description:** Validates solution entered in MIPStart. If the solver engine printed messages indicating that the initial feasible solution that you entered in [`start`](#mip.Model.start) is not valid then you can call this method to help discovering which set of variables is causing infeasibility. The current version is quite simple: the model is relaxed and one variable entered in mipstart is fixed per iteration, indicating if the model still feasible or not. ### var_by_name(name: str) * **Description:** Searches a variable by its name. * **Parameters:** * **name** (*str*) – The name of the variable to search for. * **Return type:** Optional[[Var](#mip.Var)] * **Returns:** Variable or None if not found ### write(file_path: str) * **Description:** Saves a MIP model or an initial feasible solution. One of the following file name extensions should be used to define the contents of what will be saved: `.lp` for MIP model in LP file format, `.mps` for MIP model in MPS file format, `.sol` for initial feasible solution, `.bas` for optimal basis for the linear programming relaxation. * **Parameters:** * **file_path** (*str*) – File name ``` -------------------------------- ### Cross-Compilation Docker Build with buildx Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Build the Docker image on a powerful machine for a different architecture (e.g., ARMv6) and push it to Docker Hub. This requires Docker Hub authentication and the `buildx` plugin. ```bash docker buildx create --name mybuilder docker buildx use mybuilder docker buildx inspect --bootstrap docker login docker buildx build --platform linux/arm/v6 -t / . --push ``` -------------------------------- ### Import Python-MIP Library Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Import all necessary components from the Python-MIP library to begin. This is the first step for any Python-MIP application. ```python from mip import * ``` -------------------------------- ### Facility Location Problem Model Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md Models a facility location problem with demand, distances, plant capacities, and installation costs. Uses special ordered sets (SOS) for constraints. ```python from mip import Model, minimize, xsum, OptimizationStatus from math import sqrt, log from itertools import product d = {1: 302, 2: 273, 3: 275, 4: 266, 5: 287, 6: 296, 7: 297, 8: 310, 9: 302, 10: 309} # Assuming F, C, pf, pc, c are defined elsewhere # Example definitions for demonstration: F = [1, 2, 3, 4, 5] C = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Dummy data for pf, pc, c to make the code runnable import random def random_coords(n): return {i: (random.uniform(0, 100), random.uniform(0, 100)) for i in range(1, n + 1)} pf = random_coords(len(F)) pc = random_coords(len(C)) c = {i: random.randint(100, 500) for i in F} dist = { (f, c): round(sqrt((pf[f][0] - pc[c][0]) ** 2 + (pf[f][1] - pc[c][1]) ** 2), 1) for (f, c) in product(F, C) } m = Model() z = {i: m.add_var(ub=c[i]) for i in F} # plant capacity # Type 1 SOS: only one plant per region for r in [0, 1]: # set of plants in region r Fr = [i for i in F if r * 50 <= pf[i][0] <= 50 + r * 50] m.add_sos([(z[i], i - 1) for i in Fr], 1) # amount that plant i will supply to client j x = {(i, j): m.add_var() for (i, j) in product(F, C)} # satisfy demand for j in C: m += xsum(x[(i, j)] for i in F) == d[j] # SOS type 2 to model installation costs for each installed plant y = {i: m.add_var() for i in F} for f in F: D = 6 # nr. of discretization points, increase for more precision v = [c[f] * (val / (D - 1)) for val in range(D)] # points # non-linear function values for points in v vn = [0 if k == 0 else 1520 * log(v[k]) for k in range(D)] # w variables w = [m.add_var() for _ in range(D)] m += xsum(w) == 1 # convexification # link to z vars m += z[f] == xsum(v[k] * w[k] for k in range(D)) # link to y vars associated with non-linear cost m += y[f] == xsum(vn[k] * w[k] for k in range(D)) m.add_sos([(w[k], v[k]) for k in range(D)], 2) # plant capacity for i in F: m += z[i] >= xsum(x[(i, j)] for j in C) # objective function m.objective = minimize( xsum(dist[i, j] * x[i, j] for (i, j) in product(F, C)) + xsum(y[i] for i in F) ) m.optimize() if m.num_solutions: print("Solution with cost {} found.".format(m.objective_value)) print("Facilities capacities: {} ".format([z[f].x for f in F])) print("Facilities cost: {}".format([y[f].x for f in F])) # sanity checks opt = 99733.94905406 if m.status == OptimizationStatus.OPTIMAL: assert abs(m.objective_value - opt) <= 0.01 elif m.status == OptimizationStatus.FEASIBLE: assert m.objective_value >= opt - 0.01 else: assert m.status not in [OptimizationStatus.INFEASIBLE, OptimizationStatus.UNBOUNDED] ``` -------------------------------- ### Var.x / Var.xi(k) Source: https://context7.com/coin-or/python-mip/llms.txt Query solution values for variables. `Var.x` returns the value in the best solution, while `Var.xi(k)` returns the value in the k-th solution from the solution pool. ```APIDOC ## `Var.x` / `Var.xi()` — Query solution values `Var.x` returns the value of the variable in the best solution found. `Var.xi(k)` returns the value in the k-th solution from the solution pool (0-indexed, where 0 is the best). ```python from mip import Model, xsum, maximize, BINARY m = Model() m.sol_pool_size = 5 # keep up to 5 solutions p = [10, 13, 18, 31, 7, 15] w = [11, 15, 20, 35, 10, 33] c, I = 47, range(len(w)) x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c m.optimize() print(f"Solutions in pool: {m.num_solutions}") print(f"Objective values: {m.objective_values}") # Best solution best = [i for i in I if x[i].x >= 0.99] print(f"Best selection: {best}") # Second-best solution (if available) if m.num_solutions >= 2: second = [i for i in I if x[i].xi(1) >= 0.99] print(f"2nd-best selection: {second}, cost: {m.objective_values[1]}") ``` ``` -------------------------------- ### SubTourCutGenerator - Custom Cut Generation Source: https://context7.com/coin-or/python-mip/llms.txt Implement a custom cut generator by subclassing `ConstrsGenerator` and overriding the `generate_constrs` method. This example shows how to add sub-tour elimination cuts for the Traveling Salesperson Problem (TSP). ```APIDOC ## `ConstrsGenerator` — Cut callbacks and lazy constraints Subclass `ConstrsGenerator` and implement `generate_constrs()` to inject custom cutting planes or lazy constraints during branch-and-cut. Assign to `model.cuts_generator` and/or `model.lazy_constrs_generator`. ```python from itertools import product from mip import Model, xsum, BINARY, minimize, ConstrsGenerator, CutPool import networkx as nx class SubTourCutGenerator(ConstrsGenerator): """Generates sub-tour elimination cuts for TSP.""" def __init__(self, x_, V_): self.x, self.V = x_, V_ def generate_constrs(self, model: Model, depth: int = 0, npass: int = 0): xf = model.translate(self.x) # translate to pre-processed model vars V_ = self.V cp = CutPool() G = nx.DiGraph() for (u, v) in product(V_, V_): if u != v and xf[u][v]: G.add_edge(u, v, capacity=xf[u][v].x) for (u, v) in product(V_, V_): if u == v: continue val, (S, _) = nx.minimum_cut(G, u, v) if val <= 0.99: cut = xsum(xf[i][j] for i in S for j in S if i != j and xf[i][j]) <= len(S) - 1 cp.add(cut) for cut in cp.cuts: model += cut n = 15 V = set(range(n)) import random; random.seed(1) c = [[random.randint(1, 50) if i != j else 0 for j in V] for i in V] model = Model() x = [[model.add_var(var_type=BINARY) for j in V] for i in V] model.objective = minimize(xsum(c[i][j] * x[i][j] for i in V for j in V)) for i in V: model += xsum(x[i][j] for j in V - {i}) == 1 model += xsum(x[j][i] for j in V - {i}) == 1 # Register cut generator (called at every fractional node) model.cuts_generator = SubTourCutGenerator(x, V) # Also use as lazy constraint generator (called at integer nodes) model.lazy_constrs_generator = SubTourCutGenerator(x, V) model.optimize(max_seconds=60) print(f"Status: {model.status}, Tour length: {model.objective_value}") ``` ``` -------------------------------- ### Local Docker Build Source: https://github.com/coin-or/python-mip/blob/master/docs/install.md Build the Docker image on the same device where the code will run. This can be time-consuming for resource-constrained devices like Raspberry Pi. ```bash docker build -t . ``` -------------------------------- ### Create a New Optimization Model Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Instantiate a Model object to represent your optimization problem. By default, it creates a minimization problem using the CBC solver. ```python m = Model() ``` -------------------------------- ### Optimize Model with Time Limit and Gap Tolerance Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Execute the optimization process with a maximum time limit and a specified gap tolerance for concluding the search. Handles different optimization statuses and prints solution details. ```python m.max_gap = 0.05 status = m.optimize(max_seconds=300) if status == OptimizationStatus.OPTIMAL: print('optimal solution cost {} found'.format(m.objective_value)) elif status == OptimizationStatus.FEASIBLE: print('sol.cost {} found, best possible: {}'.format(m.objective_value, m.objective_bound)) elif status == OptimizationStatus.NO_SOLUTION_FOUND: print('no feasible solution found, lower bound is: {}'.format(m.objective_bound)) if status == OptimizationStatus.OPTIMAL or status == OptimizationStatus.FEASIBLE: print('solution:') for v in m.vars: if abs(v.x) > 1e-6: # only printing non-zeros print('{} : {}'.format(v.name, v.x)) ``` -------------------------------- ### Serialize and Deserialize Models with write/read Source: https://context7.com/coin-or/python-mip/llms.txt Use `Model.write()` to save models in LP or MPS formats, and solutions/bases in SOL/BAS formats. The file extension determines the format. `Model.read()` loads a model from a file, clearing the existing model. ```python from mip import Model, xsum, BINARY, OptimizationStatus m = Model() x = [m.add_var(var_type=BINARY, name=f"x{i}") for i in range(4)] m.objective = x[0] + 2*x[1] + 3*x[2] + x[3] m += x[0] + x[1] + x[2] + x[3] <= 2 # Save model to LP format (human-readable) m.write("model.lp") # Save model to MPS format (wider compatibility) m.write("model.mps") # Load model from file (clears existing model) m2 = Model() m2.read("model.lp") print(f"Loaded: {m2.num_cols} vars, {m2.num_rows} constraints, {m2.num_nz} nzs") # Optimize and save the MIP start solution m2.optimize() if m2.status == OptimizationStatus.OPTIMAL: m2.write("solution.sol") # save for warm-starting next run # Load a warm start solution into a model m3 = Model() m3.read("model.lp") m3.read("solution.sol") # loads as MIPStart m3.optimize() ``` -------------------------------- ### Define and Solve an Optimization Model Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md This snippet shows how to define an optimization model, add variables, set an objective function, and add constraints. It then optimizes the model and prints the results. ```python from mip import Model, BINARY, minimize, xsum from itertools import product # Assume N, d, r are defined elsewhere # Example definitions (replace with actual values if available): N = [0, 1] # Example nodes d = { (0, 0): 10, (0, 1): 5, (1, 0): 5, (1, 1): 10 } # Example distances r = {0: 1, 1: 1} # Example requirements U = range(sum(d[i][j] for (i, j) in product(N, N)) + sum(el for el in r.values())) m = Model() x = [[m.add_var('x({},{})'.format(i, c), var_type=BINARY) for c in U] for i in N] z = m.add_var('z') m.objective = minimize(z) for i in N: m += xsum(x[i][c] for c in U) == r[i] for i, j, c1, c2 in product(N, N, U, U): if i != j and c1 <= c2 < c1+d[i][j]: m += x[i][c1] + x[i][c2] <= 1 for i, c1, c2 in product(N, U, U): if c1 < c2 < c1+d[i][i]: m += x[i][c1] + x[i][c2] <= 1 for i, c in product(N, U): m += z >= (c+1)*x[i][c] m.optimize(max_nodes=30) if m.num_solutions: for i in N: print('Channels of node %d: %s' % (i, [c for c in U if x[i][c].x >= 0.99])) ``` ``` -------------------------------- ### Solve 0/1 Knapsack Problem Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md Use this snippet to model and solve the 0/1 knapsack problem. It defines items with profits and weights, a knapsack capacity, and optimizes the selection of items to maximize profit. ```default from mip import Model, xsum, maximize, BINARY p = [10, 13, 18, 31, 7, 15] w = [11, 15, 20, 35, 10, 33] c, I = 47, range(len(w)) m = Model("knapsack") x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c m.optimize() selected = [i for i in I if x[i].x >= 0.99] print("selected items: {}".format(selected)) ``` -------------------------------- ### Automated Release Tagging and Pushing Source: https://github.com/coin-or/python-mip/blob/master/RELEASE-ANNOUNCEMENT.md Tagging a new version and pushing tags to trigger automated releases via GitHub Actions. This process builds and uploads the package to PyPI. ```bash git tag v1.17.1 && git push --tags ``` -------------------------------- ### read(path: str) Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Reads a MIP model or an initial feasible solution from a file. Supported file extensions include .lp, .mps, .sol, and .bas. Reading a new problem clears the current model's variables, constraints, and parameters. ```APIDOC ## read(path: str) ### Description Reads a MIP model or an initial feasible solution from a file. Supported file extensions include .lp, .mps, .sol, and .bas. Reading a new problem clears the current model's variables, constraints, and parameters. ### Parameters #### Path Parameters - **path** (*str*) – file name ### File Formats - `.lp`: mip model in LP file format. - `.mps`: mip model in MPS file format. - `.sol`: initial integer feasible solution. - `.bas`: optimal basis for the linear programming relaxation. ``` -------------------------------- ### Track Bound Evolution with Model.search_progress_log Source: https://context7.com/coin-or/python-mip/llms.txt Enable logging to record the time-series of primal and dual bound improvements during the search. Useful for diagnosing solver performance. ```python from mip import Model, xsum, maximize, BINARY m = Model() m.store_search_progress_log = True # enable logging p = [10, 13, 18, 31, 7, 15, 9, 22, 5, 12] w = [11, 15, 20, 35, 10, 33, 8, 25, 6, 18] c, I = 60, range(len(w)) x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c m.optimize(max_seconds=30) log = m.search_progress_log print(f"Log entries: {len(log.log)}") for entry in log.log[:5]: # Each entry: (time_seconds, (lower_bound, upper_bound)) t, (lb, ub) = entry print(f" t={t:.2f}s lb={lb:.2f} ub={ub:.2f}") ``` -------------------------------- ### Query Solution Values with Var.x and Var.xi() Source: https://context7.com/coin-or/python-mip/llms.txt Access the value of a variable in the best solution using `Var.x`. Use `Var.xi(k)` to retrieve the value from the k-th solution in the solution pool (0-indexed). Ensure `Model.sol_pool_size` is set to store multiple solutions. ```python from mip import Model, xsum, maximize, BINARY m = Model() m.sol_pool_size = 5 # keep up to 5 solutions p = [10, 13, 18, 31, 7, 15] w = [11, 15, 20, 35, 10, 33] c, I = 47, range(len(w)) x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c m.optimize() print(f"Solutions in pool: {m.num_solutions}") print(f"Objective values: {m.objective_values}") # Best solution best = [i for i in I if x[i].x >= 0.99] print(f"Best selection: {best}") # Second-best solution (if available) if m.num_solutions >= 2: second = [i for i in I if x[i].xi(1) >= 0.99] print(f"2nd-best selection: {second}, cost: {m.objective_values[1]}") ``` -------------------------------- ### Model Traveling Salesman Problem Source: https://github.com/coin-or/python-mip/blob/master/docs/examples.md This code snippet sets up the Traveling Salesman Problem (TSP) using Python-MIP. It defines locations and prepares for modeling the shortest tour to visit all locations. ```default from itertools import product from sys import stdout as out from mip import Model, xsum, minimize, BINARY # names of places to visit places = ['Antwerp', 'Bruges', 'C-Mine', 'Dinant', 'Ghent', 'Grand-Place de Bruxelles', 'Hasselt', 'Leuven', 'Mechelen', 'Mons', 'Montagne de Bueren', 'Namur', 'Remouchamps', 'Waterloo'] ``` -------------------------------- ### Iterate Through Solutions in Solution Pool Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Access and print details of multiple feasible solutions found during optimization, such as routes and their lengths, from the solution pool. ```python for k in range(model.num_solutions): print('route {} with length {}'.format(k, model.objective_values[k])) for (i, j) in product(range(n), range(n)): if x[i][j].xi(k) >= 0.98: print('\tarc ({},{})'.format(i,j)) ``` -------------------------------- ### Read Model from LP File and Print Properties Source: https://github.com/coin-or/python-mip/blob/master/docs/quickstart.md Read a MIP model from an LP file and print its properties. This loads variables, constraints, and non-zeros from the file. ```python m.read('model.lp') print('model has {} vars, {} constraints and {} nzs'.format(m.num_cols, m.num_rows, m.num_nz)) ``` -------------------------------- ### Solve LP Relaxation with Model.optimize(relax=True) Source: https://context7.com/coin-or/python-mip/llms.txt Temporarily treats all integer/binary variables as continuous for a single solve. Use Model.relax() to permanently convert integer variables to continuous. ```python from mip import Model, xsum, BINARY m = Model() x = [m.add_var(var_type=BINARY, name=f"x{i}") for i in range(5)] m.objective = xsum([3, 1, 4, 1, 5][i] * x[i] for i in range(5)) m += xsum(x) <= 2 # Solve LP relaxation (variables stay BINARY for integer solve later) m.optimize(relax=True) print("LP relaxation value:", m.objective_value) for v in m.vars: print(f" {v.name} = {v.x:.4f}") # fractional values possible # Now solve integer version m.optimize() print("MIP optimal value:", m.objective_value) ``` -------------------------------- ### Automatic Cutting Plane Generation Source: https://github.com/coin-or/python-mip/blob/master/docs/custom.md Demonstrates the automatic generation of cutting planes using the `generate_cuts()` method when a custom separation routine does not find any more violated inequalities. This is useful for strengthening the LP relaxation with standard cut types. ```python if not newConstraints and m.solver_name.lower() == "cbc": cp = m.generate_cuts([CutType.GOMORY, CutType.MIR, CutType.ZERO_HALF, CutType.KNAPSACK_COVER]) if cp.cuts: m += cp newConstraints = True ``` -------------------------------- ### Optimize Model with Limits and Status Checks Source: https://context7.com/coin-or/python-mip/llms.txt Use `Model.optimize()` to solve the model using the Branch-and-Cut algorithm. It accepts optional time, node, and solution limits, and returns an `OptimizationStatus`. Setting `relax=True` solves only the LP relaxation. ```python from mip import Model, xsum, minimize, BINARY, OptimizationStatus m = Model() n = 6 c = [1, 3, 2, 5, 4, 6] w = [2, 3, 4, 5, 1, 2] x = [m.add_var(var_type=BINARY) for _ in range(n)] m.objective = minimize(xsum(c[i] * x[i] for i in range(n))) m += xsum(w[i] * x[i] for i in range(n)) >= 7 m.max_mip_gap = 0.01 # stop within 1% of optimal status = m.optimize(max_seconds=60, max_nodes=1000) if status == OptimizationStatus.OPTIMAL: print(f"Optimal cost: {m.objective_value}") elif status == OptimizationStatus.FEASIBLE: print(f"Feasible cost: {m.objective_value}, bound: {m.objective_bound}, gap: {m.gap:.2%}") elif status == OptimizationStatus.NO_SOLUTION_FOUND: print(f"No solution found, lower bound: {m.objective_bound}") elif status == OptimizationStatus.INFEASIBLE: print("Model is infeasible") # Print all non-zero variables for v in m.vars: if abs(v.x) > 1e-6: print(f" {v.name} = {v.x}") ``` -------------------------------- ### Model Class Source: https://context7.com/coin-or/python-mip/llms.txt The central class for all modeling activity. Instantiating Model automatically selects the best available solver. The sense defaults to MINIMIZE; pass sense=MAXIMIZE to maximize. The solver can be forced with solver_name=CBC, solver_name=GRB, or solver_name=HIGHS. ```APIDOC ## Model — Create and configure a MIP model ### Description The central class for all modeling activity. Instantiating `Model` automatically selects the best available solver (Gurobi if available, otherwise CBC). The sense defaults to `MINIMIZE`; pass `sense=MAXIMIZE` to maximize. The solver can be forced with `solver_name=CBC`, `solver_name=GRB`, or `solver_name=HIGHS`. ### Parameters - **name** (str) - Optional - Name of the model. - **sense** (int) - Optional - Optimization sense, `MAXIMIZE` or `MINIMIZE`. - **solver_name** (int) - Optional - Name of the solver to use (e.g., `CBC`, `GRB`, `HIGHS`). ### Request Example ```python from mip import Model, MAXIMIZE, MINIMIZE, CBC, GRB # Minimization model using CBC (default) m_min = Model() # Maximization model using Gurobi m_max = Model(name="my_problem", sense=MAXIMIZE, solver_name=GRB) # Force CBC even if Gurobi is installed m_cbc = Model(sense=MINIMIZE, solver_name=CBC) print(m_min.sense) # 'MIN' print(m_max.sense) # 'MAX' ``` ``` -------------------------------- ### Model.write() / Model.read() Source: https://context7.com/coin-or/python-mip/llms.txt Serialize and deserialize models to/from various file formats including LP, MPS, SOL, and BAS. The file extension determines the format used. ```APIDOC ## `Model.write()` / `Model.read()` — Serialize and deserialize models Saves/loads models in LP, MPS formats, and solutions/bases in SOL/BAS formats. The file extension determines the format. ```python from mip import Model, xsum, BINARY, OptimizationStatus m = Model() x = [m.add_var(var_type=BINARY, name=f"x{i}") for i in range(4)] m.objective = x[0] + 2*x[1] + 3*x[2] + x[3] m += x[0] + x[1] + x[2] + x[3] <= 2 # Save model to LP format (human-readable) m.write("model.lp") # Save model to MPS format (wider compatibility) m.write("model.mps") # Load model from file (clears existing model) m2 = Model() m2.read("model.lp") print(f"Loaded: {m2.num_cols} vars, {m2.num_rows} constraints, {m2.num_nz} nzs") # Optimize and save the MIP start solution m2.optimize() if m2.status == OptimizationStatus.OPTIMAL: m2.write("solution.sol") # save for warm-starting next run # Load a warm start solution into a model m3 = Model() m3.read("model.lp") m3.read("solution.sol") # loads as MIPStart m3.optimize() ``` ``` -------------------------------- ### Upgrade MiP Package Source: https://github.com/coin-or/python-mip/blob/master/RELEASE-ANNOUNCEMENT.md Use this command to upgrade the MiP package to the latest version. ```bash pip install --upgrade mip ``` -------------------------------- ### Save MIP Model or Solution Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md The `write` method can be used to save the MIP model in various formats like LP, MPS, or to save an initial feasible solution or optimal basis. ```python m.write("model.lp") ``` ```python m.write("model.mps") ``` ```python m.write("solution.sol") ``` ```python m.write("basis.bas") ``` -------------------------------- ### Optimize MIP Model with Time Limit Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Optimize the current MIP model with a specified time limit in seconds. Other parameters like max_nodes and max_solutions can also be set. ```python m.optimize(max_seconds=300) ``` -------------------------------- ### Automatic Cut Generation with Model.generate_cuts() Source: https://context7.com/coin-or/python-mip/llms.txt Manually triggers one round of cut generation for various cut types (GOMORY, GMI, MIR, ZERO_HALF) on the current LP relaxation. Useful in explicit cutting-plane loops. ```python from mip import Model, xsum, BINARY, OptimizationStatus, CutType m = Model() n = 8 c = [3, 1, 4, 1, 5, 9, 2, 6] w = [2, 3, 1, 4, 2, 3, 2, 1] x = [m.add_var(var_type=BINARY) for _ in range(n)] m.objective = xsum(c[i] * x[i] for i in range(n)) m += xsum(w[i] * x[i] for i in range(n)) <= 10 # Solve LP relaxation m.optimize(relax=True) print(f"LP relaxation value: {m.objective_value}") # Generate cuts automatically if m.status == OptimizationStatus.OPTIMAL: cp = m.generate_cuts( cut_types=[CutType.GOMORY, CutType.GMI, CutType.MIR, CutType.ZERO_HALF], max_cuts=64, min_viol=1e-4, ) print(f"Generated {len(cp.cuts)} cuts") if cp.cuts: m += cp # add all cuts to the model m.optimize() print(f"After cuts: {m.objective_value}") ``` -------------------------------- ### Creating a Constraint with LinExpr Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Demonstrates adding a constraint to a model using a linear expression. The constraint can be an inequality or equality. ```python m += xsum(x[i] for i in range(n)) == 1 ``` -------------------------------- ### copy Source: https://github.com/coin-or/python-mip/blob/master/docs/classes.md Creates a copy of the current model, optionally specifying a solver name for the copied model. ```APIDOC ## copy(solver_name: str = '') -> [Model](#mip.Model) ### Description Creates a copy of the current model. ### Parameters * **solver_name** (*str*) – solver name (optional) ### Return type [Model](#mip.Model) ### Returns clone of current model ```