混合整數非線性規劃 ortools系列 整數規劃

2021-10-12 08:16:49 字數 4714 閱讀 3387

ortools系列-整數規劃

有一些問題,要求一些但不是全部變數約束為整數,這類問題可以用混合整數規劃(mip)來解決,混合整數規劃也稱為混合整數線性規劃(milp)。這裡有幾個例子:

or-tools提供了幾種方法求解此類問題:

其中前兩個是一般性的求解器,能解決任何整數規劃問題,最後乙個最小成本流求解器用於求解那些能建模成網路流的問題,對於這類特殊問題,最小成本流求解器比一般的整數規劃和約束規劃要快的多。

ortools提供乙個混合整數規劃的介面用於呼叫不同的求解器,ortools內建了coin-or branch and cut (cbc),當然你也可以使用第三方的求解器,比如scip,glpk,gurobi。cbc是乙個開源的混合整數規劃求解器,用c++開發。

我們看下面這個問題:

問題的解空間如下:

我們看ortools是如何解決這個問題的。

from ortools.linear_solver import pywraplp

def main():

# 首先,呼叫cbc求解器

# 還記得我們在lp問題中呼叫的求解器嗎,

# 是 pywraplp.solver.glop_linear_programming

solver = pywraplp.solver('solveintegerproblem',

pywraplp.solver.cbc_mixed_integer_programming)

# 和lp問題一樣,定義變數 x,y 並指定其定義域

# 這裡需要注意,我們定義的是int型別的變數

x = solver.intvar(0.0, solver.infinity(), 'x')

y = solver.intvar(0.0, solver.infinity(), 'y')

# 新增約束,方法和lp一樣,通過制定係數來新增約束

# 如果能像cp-sat那麼方便就好了

# x + 7 * y <= 17.5

constraint1 = solver.constraint(-solver.infinity(), 17.5)

constraint1.setcoefficient(x, 1)

constraint1.setcoefficient(y, 7)

# 新增約束

# x <= 3.5

constraint2 = solver.constraint(-solver.infinity(), 3.5)

constraint2.setcoefficient(x, 1)

constraint2.setcoefficient(y, 0)

# 定義目標函式

# maximize x + 10 * y.

objective = solver.objective()

objective.setcoefficient(x, 1)

objective.setcoefficient(y, 10)

objective.setmaximization()

# 求解問題,並列印結果,後面的**就很簡單了

result_status = solver.solve()

# the problem has an optimal solution.

assert result_status == pywraplp.solver.optimal

# the solution looks legit (when using solvers other than

# glop_linear_programming, verifying the solution is highly recommended!).

assert solver.verifysolution(1e-7, true)

print('number of variables =', solver.numvariables())

print('number of constraints =', solver.numconstraints())

# the objective value of the solution.

print('optimal objective value = %d' % solver.objective().value())

print()

# the value of each variable in the solution.

variable_list = [x, y]

for variable in variable_list:

print('%s = %d' % (variable.name(), variable.solution_value()))

if __name__ == '__main__':

main()

# 結果

number of variables = 2

number of constraints = 2

optimal objective value = 23

x = 3

y = 2

通過**可以看到,其實和lp問題基本一樣,思路是很清晰,就是囉嗦呢。

前面我們講了cbc解mip的問題。約束規劃是一種有別於經典優化理論的優化方法。cp的基礎是可行性(尋找問題的可行解),側重於約束和變數,而不是目標函式。對於許多態別的問題,cp可以比mip求解器更快地找到最優解。

那我們應該如何選擇cp還是mip呢。

對於乙個可行點必須滿足所有約束的標準整數規劃問題,mip求解器速度更快。在這種情況下,可行集是凸的:對於集合中的任意兩點,連線它們的線段完全位於集合中。

另一方面,對於高度非凸可行集的問題,cp-sat求解器通常比mip求解器快。當可行集由許多由or連線的約束定義時,就會出現這樣的問題,or意味著乙個點只需要滿足其中乙個約束就可以是可行的。

為了提高計算速度,cp-sat求解器和原始cp求解器都對整數進行運算。要解決某些約束具有非整數項的問題,必須首先將這些約束轉換為乙個足夠大的整數。下面的示例說明了這一點。

我們來看**:

from ortools.sat.python import cp_model

def main():

# 首先是建立模型

model = cp_model.cpmodel()

# 定義變數,指定變數的範圍

# 根據題目可以知道,x,y,z 的最大值肯定不超過50

# var_upper_bound 相當於減少了搜尋空間範圍

# 注意,我們這裡定義的是整數變數

var_upper_bound = max(50, 45, 37)

x = model.newintvar(0, var_upper_bound, 'x')

y = model.newintvar(0, var_upper_bound, 'y')

z = model.newintvar(0, var_upper_bound, 'z')

# 新增約束

# 注意到,我們第乙個約束條件是 x + 7⁄2 y + 3⁄2 z ≤ 25

# 但是 cp-sat 只能處理整數問題,所以需要對第乙個約束處理,使得係數全部是整數

# 方法很簡單,左邊右邊都乘以2就可以了

model.add(2 * x + 7 * y + 3 * z <= 50)

# 新增第二個約束

model.add(3 * x - 5 * y + 7 * z <= 45)

# 新增第三個約束

model.add(5 * x + 2 * y - 6 * z <= 37)

# 定義目標函式

model.maximize(2 * x + 2 * y + 3 * z)

# 求解並列印結果

solver = cp_model.cpsolver()

status = solver.solve(model)

if status == cp_model.optimal:

print('maximum of objective function: %i' % solver.objectivevalue())

print()

print('x value: ', solver.value(x))

print('y value: ', solver.value(y))

print('z value: ', solver.value(z))

if __name__ == '__main__':

main()

# 結果

maximum of objective function: 35

x value: 7

y value: 3

z value: 5

看起來也不複雜呢,因為我們的例子也不複雜啊,現實生活中的大部分問題都是大規模整數規劃問題,說不定跑半天都沒出結構。

ortools的文件中還是乙個例子,是用 original-cp 來求解上面的問題,和之前一樣的套路,感興趣的同學可以看看。

大家看完記得關注點贊.

master蘇.

線性規劃,整數規劃,非線性規劃,二次規劃

tx。約束條件一般有如下形式。對應的函式形式linprog c,a,b 它的返回值是向量x 的值 可轉化為線性規劃的問題 形如min x1 x2 x3 xn s.t.ax b 其中 x x1 xn t 要把上面的問題變換成線性規劃問題,只要注意到事實 對任意的xi 存在 ui vi 0 滿足 xi ...

非線性規劃

1.基本形式和求解模式。2.掌握凸函式和凸規劃的概念及性質。3.掌握0.618法。4.無約束優化的最優性質,熟練運用最速下降法和共軛方法。約束最優化的性質,懲罰函式。minf x s.t gi x 0 i 1,2,ph j x 0,j 1,2 q可行域為 x x r n gi x 0,i 1,2,p...

Matlab非線性規劃

在matlab非線性規劃數學模型可以寫成一下形式 minf x s.t.begin ax le b aeq x beq c x le 0 ceq x 0 end f x 為目標函式,a,b,aeq,beq為線性約束對應的矩陣和向量,c x ceq x 為非線性約束。matlab求解命令為 x fmi...