Python Interface

Installation guide

Currently, the Python interface of Cardinal Optimizer supports Python versions 2.7, 3.6-3.12. Among them, for Python 3.8-3.12 versions, COPT’s MacOS-Universal can provide support. For Python 2.7, 3.6-3.7 versions, only MacOS-X86 is available.

Before using the Python interface, please ensure that COPT has been installed and configured correctly. For details, please refer to How to install the Cardinal Optimizer. Users can download Python from Anaconda distribution or Python official distribution . We recommend users install the Anaconda distribution, because it is more user-friendly and convenient for Python novices (For Windows, please don’t install Python via Microsoft Store). If you use official Python distribution or Python shipped with system, then make sure you have installed the pip and setuptools Python packages beforehand.

Note

We recommend using versions 3.8-3.12 because the minimum version requirement for Matrix Modeling function of the COPT-Python interface is 3.8. Versions 2.7 and 3.6-3.7 are not recommended unless necessary.

Windows

Method 1: via pip install (recommended)

Open the cmd command window (if Python is an Anaconda distribution, open the Anaconda command line window) and enter the following command:

pip install coptpy

If an older version of the coptpy package has been installed, please open the cmd command window (if Python is an Anaconda distribution, open the Anaconda command line window) and enter the following command to upgrade to the latest version of the coptpy package:

pip install --upgrade coptpy

Method 2: via COPT installation package

For Windows, assuming the installation path of COPT is: "C:\Program Files\COPT", please switch to the directory "C:\Program Files\COPT\lib\python" and execute the following commands on command line:

python setup.py install

Note that if COPT is installed on the system disk, you need to execute with administrator privileges to open the command prompt. To test whether the Python interface is installed correctly, users can switch to the directory "C:\Program Files\COPT\examples\python" and execute the following commands on the command line:

python lp_ex1.py

If the model is solved correctly, it means that the Python interface of COPT has been installed correctly.

Note If you use the official release of Python 3.8, assume that its installation path is: "C:\Program Files\Python38", you need to copy the copt_cpp.dll file in the "bin" subdirectory of the COPT installation path to "C:\Program Files\Python38\Lib\site-packages\coptpy" to solve the problem of dynamic library dependency.

Currently, coptpy already supports type hints, users can execute the following command in the command line window (if Python is the Anaconda release version, please open Anaconda Prompt):

pip install coptpy-stubs

After successfully installed, when writing code in the Python IDE, you will be prompted to complete the variable name and the value of the function parameter.

Linux

Method 1: via pip install (recommended)

Open the terminal and enter the following command:

pip install coptpy

If an older version of the coptpy package has been installed, please open the terminal and enter the following command to upgrade to the latest version of the coptpy package:

pip install --upgrade coptpy

Method 2: via COPT installation package

For Linux, suppose the installation path of COPT is: /opt/copt71, please switch to the directory /opt/copt71/lib/python and execute the following commands on terminal:

sudo python setup.py install

For users using Python from Anaconda distribution, if above commands fails, assuming the installation path of Anaconda is: "/opt/anaconda3", please execute the following commands instead on terminal to install the Python interface of COPT:

sudo /opt/anaconda3/bin/python setup.py install

To test whether the Python interface is installed correctly, users can switch to the directory /opt/copt71/examples/python and execute the following commands on terminal:

python lp_ex1.py

If the model solved correctly, it means that the Python interface of COPT has been installed correctly.

Currently, coptpy already supports type hints, users can execute the following command in the terminal:

pip install coptpy-stubs

After successfully installed, when writing code in the Python IDE, you will be prompted to complete the variable name and the value of the function parameter.

MacOS

Method 1: via pip install (recommended)

Open the terminal and enter the following command:

pip install coptpy

If an older version of the coptpy package has been installed, please open the terminal and enter the following command to upgrade to the latest version of the coptpy package:

pip install --upgrade coptpy

Method 2: via COPT installation package

For MacOS, assuming that the installation path of COPT is: /Applications/copt71, please switch the directory to /Applications/copt71/lib/python and execute the following commands on terminal:

sudo python setup.py install

To test whether the Python interface is installed correctly, users can switch to the directory /Applications/copt71/examples/python and execute the following commands on terminal:

python lp_ex1.py

If the model solved correctly, it means that the Python interface of COPT has been installed correctly.

Currently, coptpy already supports type hints, users can execute the following command in the terminal:

pip install coptpy-stubs

After successfully installed, when writing code in the Python IDE, you will be prompted to complete the variable name and the value of the function parameter.

Example details

This chapter illustrate the use of C interface of Cardinal Optimizer through a simple Python example. The problem to solve is shown in Eq. 5:

(5)\[\begin{split}\text{Maximize: } & \\ & 1.2 x + 1.8 y + 2.1 z \\ \text{Subject to: } & \\ & 1.5 x + 1.2 y + 1.8 z \leq 2.6 \\ & 0.8 x + 0.6 y + 0.9 z \geq 1.2 \\ \text{Bounds: } & \\ & 0.1 \leq x \leq 0.6 \\ & 0.2 \leq y \leq 1.5 \\ & 0.3 \leq z \leq 2.8\end{split}\]

The source code for solving the above problem using Python API of Cardinal Optimizer is shown in Listing 6:

Listing 6 lp_ex1.py
 1#
 2# This file is part of the Cardinal Optimizer, all rights reserved.
 3#
 4
 5"""
 6The problem to solve:
 7
 8  Maximize:
 9    1.2 x + 1.8 y + 2.1 z
10
11  Subject to:
12    1.5 x + 1.2 y + 1.8 z <= 2.6
13    0.8 x + 0.6 y + 0.9 z >= 1.2
14
15  where:
16    0.1 <= x <= 0.6
17    0.2 <= y <= 1.5
18    0.3 <= z <= 2.8
19"""
20
21import coptpy as cp
22from coptpy import COPT
23
24# Create COPT environment
25env = cp.Envr()
26
27# Create COPT model
28model = env.createModel("lp_ex1")
29
30# Add variables: x, y, z
31x = model.addVar(lb=0.1, ub=0.6, name="x")
32y = model.addVar(lb=0.2, ub=1.5, name="y")
33z = model.addVar(lb=0.3, ub=2.8, name="z")
34
35# Add constraints
36model.addConstr(1.5*x + 1.2*y + 1.8*z <= 2.6)
37model.addConstr(0.8*x + 0.6*y + 0.9*z >= 1.2)
38
39# Set objective function
40model.setObjective(1.2*x + 1.8*y + 2.1*z, sense=COPT.MAXIMIZE)
41
42# Set parameter
43model.setParam(COPT.Param.TimeLimit, 10.0)
44
45# Solve the model
46model.solve()
47
48# Analyze solution
49if model.status == COPT.OPTIMAL:
50  print("Objective value: {}".format(model.objval))
51  allvars = model.getVars()
52
53  print("Variable solution:")
54  for var in allvars:
55    print(" x[{0}]: {1}".format(var.index, var.x))
56
57  print("Variable basis status:")
58  for var in allvars:
59    print(" x[{0}]: {1}".format(var.index, var.basis))
60
61  # Write model, solution and modified parameters to file
62  model.write("lp_ex1.mps")
63  model.write("lp_ex1.bas")
64  model.write("lp_ex1.sol")
65  model.write("lp_ex1.par")

We will explain how to use the Python API step by step based on code above, please refer to C API Reference for detailed usage of Python API.

Import Python interface

To use the Python interface of COPT, users need to import the Python interface library first.

import coptpy as cp
from coptpy import COPT

Create environment

To solve any problem with COPT, users need to create optimization environment before creating any model.

# Create COPT environment
env = cp.Envr()

Create model

If the optimization environment was created successfully, users need to create the model to solve, which includes variables and constraints information.

# Create COPT model
model = env.createModel("lp_ex1")

Add variables

Users can specify information such as objective costs, lower and upper bounds of variables when creating them. In this example, we just set the lower and upper bounds of variables and their names.

# Add variables: x, y, z
x = model.addVar(lb=0.1, ub=0.6, name="x")
y = model.addVar(lb=0.2, ub=1.5, name="y")
z = model.addVar(lb=0.3, ub=2.8, name="z")

Add constraints

After adding variables, we can then add constraints to the model.

# Add constraints
model.addConstr(1.5*x + 1.2*y + 1.8*z <= 2.6)
model.addConstr(0.8*x + 0.6*y + 0.9*z >= 1.2)

Set objective function

After adding variables and constraints, we can further specify objective function for the model.

# Set objective function
model.setObjective(1.2*x + 1.8*y + 2.1*z, sense=COPT.MAXIMIZE)

Set parameters

Users can set optimization parameters before solving the model, e.g. set optimization time limit to 10 seconds.

# Set parameter
model.setParam(COPT.Param.TimeLimit, 10.0)

Solve model

Solve the model via solve method.

# Solve the model
model.solve()

Analyze solution

When solving finished, we should query the optimization status first. If the optimization status is optimal, then we can retrieve objective value, solution and basis status of variables.

# Analyze solution
if model.status == COPT.OPTIMAL:
  print("Objective value: {}".format(model.objval))
  allvars = model.getVars()

  print("Variable solution:")
  for var in allvars:
    print(" x[{0}]: {1}".format(var.index, var.x))

  print("Variable basis status:")
  for var in allvars:
    print(" x[{0}]: {1}".format(var.index, var.basis))

Write files

Users can write current model to MPS format file, and write solution, basis status and modified parameters to file.

  # Write model, solution and modified parameters to file
  model.write("lp_ex1.mps")
  model.write("lp_ex1.bas")
  model.write("lp_ex1.sol")
  model.write("lp_ex1.par")

Best Practice

Upgrade to newer version

If users have COPT python installed and need to upgrade latest version, it is recommended to remove previous version before installing new version. To remove previous version, it is as simple as deleting the folder coptpy at site-package.

Multi-Thread Programming

COPT does not guarrantee thread safe and modelling APIs are not reentrant in general. It is safe to share COPT Envr objects among threads. However, it is not recommended to share Model objects among threads, unless you understand what you are doing. For instance, if you share the same model between two threads. One thread is responsible for modelling and solving. The other thread is used to monitor the progress and may interrupt at some circumstances, such as running out of time.

Dictionary order guarranteed after Python v3.7

As you know, Python dictionaries did not preserve the order in which items were added to them. For instance, you might type {'fruits': ['apple', 'orange'], 'veggies': ['carrot', 'pea']} and get back {'veggies': ['carrot', 'pea'], 'fruits': ['apple', 'orange']}.

However, the situation is changed. Standard dict objects preserve order in the implementation of Python 3.6. This order-preserving property is becoming a language feature in Python 3.7.

If your program has dependency on dictionary orders, install coptpy for Python v3.7 or later version. For instance, if your model is implemented in Python 2.7 as follows:

m = Envr().createModel("customized model")
vx = m.addVars(['hello', 'world'], [0, 1, 2], nameprefix = "X")
# add a constraint for each var in tupledict 'vx'
m.addConstrs(vx[key] >= 1.0 for key in vx)

Your model might end up with rows {R(hello,1), R(hello,0), R(world,1), R(world,0), R(hello,2), R(world,2)} .

Use quicksum and psdquicksum when possible

The Python interface of COPT supports building linear expression, quadratic expression and PSD expression in natural way. For linear and quadratic expression, it is recommended to use quicksum() to build expression objects. For linear and PSD expression, it is recommended to use psdquicksum() to build expression objects. Both of them implement inplace summation, which is much faster than standard plus operator.

Operate the model in batch

The Python interface of COPT supports performing batch operations on the models, such as:

  • Add multiple variables or constraints: Model.addVars()/Model.addConstrs() .

  • Set the coefficients of multiple variables in the linear constraints: Model.setCoeffs() (Note: The index pairs of variables and constraints cannot appear repeatedly).

  • Set the names of multiple variables or constraintss: Model.setNames() .

Please refer to Python API Reference: Model Class for function descriptions.