以一个简单的线性规划问题为例:
import pyoptinterface as poi
from pyoptinterface import copt
model = copt.Model()
x = model.add_variable(lb=0, name="x")
y = model.add_variable(lb=0, ub=10, name="y")
con = model.add_linear_constraint(5*x+4*y, poi.Geq, 19)
model.set_objective(2*x+3*y)
model.optimize()
x_value = model.get_value(x)
y_value = model.get_value(y)
首先声明模型,其次调用model.add_variable函数添加变量,可以设置变量的上下界和名称,随后调用model.add_linear_constraint添加线性约束条件,调用model.set_objective设置目标函数,由于使用了运算符重载,线性表达式可以由变量的四则运算直接构建,最后调用model.optimize求解优化模型,并调用model.get_value查询变量的最优解取值。
如果加入整数变量的约束,则问题转化为混合整数线性规划问题,需要在调用model.add_variable的时候声明x和y是整数变量:
import pyoptinterface as poi
from pyoptinterface import copt
model = copt.Model()
x = model.add_variable(lb=0, domain=poi.VariableDomain.Integer, name="x")
y = model.add_variable(lb=0, ub=10, domain=poi.VariableDomain.Integer, name="y")
con = model.add_linear_constraint(5*x+4*y, poi.Geq, 19)
model.set_objective(2*x+3*y)
model.optimize()
x_value = model.get_value(x)
y_value = model.get_value(y)
如果将目标函数变为二次函数,则问题转化为混合整数二次规划问题,修改目标函数即可:
import pyoptinterface as poi
from pyoptinterface import copt
model = copt.Model()
x = model.add_variable(lb=0, domain=poi.VariableDomain.Integer, name="x")
y = model.add_variable(lb=0, ub=10, domain=poi.VariableDomain.Integer, name="y")
con = model.add_linear_constraint(5*x+4*y, poi.Geq, 19)
model.set_objective(2*x*x+3*y*y)
model.optimize()
x_value = model.get_value(x)
y_value = model.get_value(y)
最后展示一个利用PyOptInterface求解8皇后问题的示例,构建8*8的0-1变量数组,建模为混合整数线性规划问题,利用HiGHS求解器找到一个可行解,并打印最终的棋盘布置。示例中我们用Numpy的多维数组储存PyOptInterface的变量对象,表明了PyOptInterface可以与其他Python生态系统中第三方包无缝配合。
import numpy as np
import pyoptinterface as poi
from pyoptinterface import highs
model = highs.Model()
N = 8
x = np.empty((N, N), dtype=object)
for i in range(N):
for j in range(N):
x[i, j] = model.add_variable(domain=poi.VariableDomain.Binary)
for i in range(N):
# 行列约束
model.add_linear_constraint(poi.quicksum(x[i, :]), poi.Eq, 1.0)
model.add_linear_constraint(poi.quicksum(x[:, i]), poi.Eq, 1.0)
for i in range(-N+1, N):
# 对角线约束
model.add_linear_constraint(poi.quicksum(x.diagonal(i)), poi.Leq, 1.0)
model.add_linear_constraint(poi.quicksum(np.fliplr(x).diagonal(i)), poi.Leq, 1.0)
model.optimize()
get_v = np.vectorize(lambda x: model.get_value(x))
x_value = get_v(x)
print(x_value.astype(int))