Gurobiの研究ノート - 行列変数と8つのクイーン問題の例
このセクションでは、変数Gurobiの行列を記述MVar
し、8例でクイーンズGurobiケースにディレクトリを解釈します
行列変数MVar
とtupledict
異なります。
変数行列は、Mvar
変数numpyのndarrayの形態、MVAR numpyの多項式の行列式を介してリニア/行列を乗算しただけ添字インデックスですMLinExpr
か、MQuadExpr
。
変数の行列を作成します。
Model.addMVar()共通
addMVar ( shape, lb=0.0, ub=GRB.INFINITY, obj=0.0, vtype=GRB.CONTINUOUS, name="" ) shape:矩阵向量的维度 lb, ub:分别为变量的上下限(可选) obj:变量在目标函数表达式中的系数(可选) vtype:变量类型(可选) x = model.addMVar(10) # 包含10个变量的一维矩阵变量 y = model.addMVar((3,4), vtype GRB.BINARY) # 3x4的0-1变量矩阵
行列変数の操作
Gurobi行列変数は行列でnumpyのように使用することができ、式を作成するには、その操作は、寸法が適合するものでなければならないことに留意すべきです。例えば、次のように式が表されます。
x + 2 y + 3 z <= 4
x + y >= 1
x, y, z binary
以下のように記述することができます
# 一维矩阵变量
x = m.addMVar(shape=3, vtype=GRB.BINARY, name="x")
# 左端项系数矩阵
A = np.array([[1,2,3],[1,1,0]])
# 右端项
rhs = np.array([4.0, -1.0])
m.addConstr(A @ x <= rhs, name ="c")
支持マトリックス演算をスライス変数[]
、:
行列の特定の要素を選択し、そのtupledict
オブジェクト(すなわち、addVars()
)でselect()
表し、*ワイルドカード演算子を使用して、後者とは異なります
行列変数の和演算をサポートしていますが、とのtupledict
異なる変数。行列変数を使用すると、select要素をスライスし、直接呼び出すsum()
機能を
y = model.addMVar((3,4), vtype GRB.BINARY) # 3x4的0-1变量矩阵
y[:,1]#选取第一列元素
オブジェクトのコントラストtuplelist
tupledict
変数model.addVars()
やmultidict()
関数を作成、インデックスが作成を通じてアクセスするために使用するだけでなく、持っているselect()
、sum()
、prod()
機能的スクリーニング要素とすぐに式を作成します。
model.addVars(*indices)
方法によって作成されたオブジェクトは、基本的にコレクションの様々なデカルト積の結果であります
x = m.addVars(2,3, vtype=GRB.BINARY)
# 生成的元素是
x(0,0) x(0,1) x(0,2)
x(1,0) x(1,1) x(1,2)
# 三个组的笛卡尔积
y = m.addVars((1,2),(1,3),(2,3))
x(1,1,2) x(1,1,3) x(1,3,2) x(1,3,3)
x(2,1,2) x(2,1,3) x(2,3,2) x(2,3,3)
tupledict
文字列型の使用をサポートするために作成されたオブジェクト、およびインデックスはワイルドカードを使用することができます
commodities = ['Pencils', 'Pens']
nodes = ['Detroit', 'Denver']
flow = m.addVars(commodities, nodes, obj=cost, name="flow")
flow.select('*','*')
# flow('pencil','Detroit') flow('pencil','Denver')
# flow('pen','Detroit') flow('pen','Denver')
八クイーンズケース
ケースは、ケースGurobiディレクトリに存在するフォルダ根目录\examples\python\matrix2.py
エイトクイーン問題は古く、よく知られた問題がされているアルゴリズムバックトラックの典型的な例を。8×8のグリッド:問題はマックスベテルは、1848年に提示した国際チェスプレーヤーであるチェス 8人の上に置い女王、それはお互いを攻撃することはできません、任意の二つの王妃が同じ行にすることはできません、です同じ行または同じスラッシュと尋ねたどのように多くの振り子方式に。(からの抜粋Baiduの百科事典)
仮定する決定変数x(i,j)
バイナリ変数、変数としては、i番目の行が配置されているクイーンj番目の列を表し、以下の条件が必要です。
(1)各列にのみクイーンを配置
(2)各列のみクイーンに配置されます
(3)各のみ正の対角の女王を置きます
(4)各対角線ランプが唯一の女王を置きます
発電機によって生成された3,4-制約は、コードは、I、N、例えば= 4、計算正対角線、対角線傾斜共感のプッシュに、全て一度に読み取ることができます
#!/usr/bin/env python3.7
# Copyright 2019, Gurobi Optimization, LLC
# This example uses the Python matrix API to formulate the n-queens
# problem; it maximizes the number queens placed on an n x n
# chessboard without threatening each other.
#
# This example demonstrates NumPy slicing.
import numpy as np
import scipy.sparse as sp
import gurobipy as gp
from gurobipy import GRB
# Size of the n x n chess board
n = 8
try:
# Create a new model
m = gp.Model("matrix2")
# Create a 2-D array of binary variables
# x[i,j]=1 means that a queen is placed at square (i,j)
x = m.addMVar((n, n), vtype=GRB.BINARY, name="x")
# Set objective - maximize number of queens
m.setObjective(x.sum(), GRB.MAXIMIZE)
# Add row and column constraints
# 为每一行、列添加约束
for i in range(n):
# At most one queen per row
# 每一行最多放置一个皇后
m.addConstr(x[i, :].sum() <= 1, name="row"+str(i))
# At most one queen per column
# 每一列最多放置一个皇后
m.addConstr(x[:, i].sum() <= 1, name="col"+str(i))
# Add diagonal constraints
# 添加对角线约束
for i in range(1, 2*n):
# At most one queen per diagonal
# 每个正对角线最多防止一个皇后
# 生成器生成对矩阵的切片索引
diagn = (range(max(0, i-n), min(n, i)), range(min(n, i)-1, max(0, i-n)-1, -1))
m.addConstr(x[diagn].sum() <= 1, name="diag"+str(i))
# At most one queen per anti-diagonal
# 每个斜对角线最多防止一个皇后
# 生成器生成对矩阵的切片索引
adiagn = (range(max(0, i-n), min(n, i)), range(max(0, n-i), min(n, 2*n-i)))
m.addConstr(x[adiagn].sum() <= 1, name="adiag"+str(i))
# Optimize model
# 开始优化模型
m.optimize()
print(x.X)
print('Queens placed: %g' % m.objVal)
except gp.GurobiError as e:
print('Error code ' + str(e.errno) + ": " + str(e))
except AttributeError:
print('Encountered an attribute error')