一、CPLEX Python的介紹
CPLEX Python是IBM CPLEX的Python介面,它可以用Python語言輕鬆地實現線性規劃(LP)、混合整數規劃(MIP)和二次規劃(QP)等問題的建模和求解。同時,CPLEX Python支持使用約束編程(Constraint Programming)和整數編程(Integer Programming)擴展問題建模能力。CPLEX Python還提供了各種方法來設置問題的參數,以滿足特定的需求。
要使用CPLEX Python求解優化模型,需要先安裝IBM CPLEX和CPLEX Python包。可以訪問IBM官方網站下載IBM ILOG CPLEX Optimization Studio和Python for CPLEX模塊。在安裝完成後,可以在Python中導入CPLEX包,開始建模和求解。
# 導入CPLEX包
import cplex
二、CPLEX Python的建模
在CPLEX Python中建模的過程主要包括下面三個步驟:
1. 定義問題
要使用CPLEX Python解決一個優化問題,需要先創建一個CPLEX對象,用於存儲問題。可以使用cplex.Cplex()
方法進行創建:
# 創建CPLEX對象
problem = cplex.Cplex()
2. 添加變數和約束
變數和約束是優化問題建模中非常重要的一部分。CPLEX Python提供了variables.add()
方法和linear_constraints.add()
方法用於添加變數和約束。
例如,如果要建立以下線性規劃問題:
$$
\begin{aligned}
&\max \quad 2x_1 + 3x_2 \\
&s.t. \quad 4x_1 + 3x_2 \leq 25 \\
& \quad 2x_1 – 5x_2 \leq 10 \\
& \quad x_1,x_2 \geq 0 \\
\end{aligned}
$$
則可以使用下面的代碼進行建模:
# 添加變數
problem.variables.add(names=['x1', 'x2'], lb=[0, 0])
# 添加約束
problem.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=['x1', 'x2'], val=[4, 3]),
cplex.SparsePair(ind=['x1', 'x2'], val=[2, -5])],
senses=['L', 'L'], rhs=[25, 10])
3. 設置問題的目標和求解方法
CPLEX Python支持不同的優化目標,例如最大化、最小化,可以使用objective.set()
方法設置問題的目標。
要將問題設置為最大化目標,可以使用以下代碼:
# 設置目標函數
problem.objective.set_sense(problem.objective.sense.maximize)
最後,還需要選擇求解問題的演算法和參數,可以使用parameters.set()
方法。
例如,可以使用以下代碼選擇求解演算法:
# 選擇求解方法
problem.set_results_stream(None)
problem.solve()
三、CPLEX Python的實例
1. 快遞配送問題
假設我們要為一家快遞公司設計一個配送方案,使得成本最小化。問題可以描述為:有10個快遞員和20個快遞站點,每個快遞員可以在每個站點中收集一定數量的貨物,然後將這些貨物遞送到指定的目的地。每個快遞員只能駕駛一輛載重量為30公斤的貨車,每個站點的貨物量不同。因此,我們需要找到最佳的配送方案,以使得所有站點的貨物能夠及時送達,同時最小化總成本。
此問題可以轉化為一個混合整數規劃問題,可以使用CPLEX Python進行建模和求解。
首先,我們需要定義決策變數,例如$x_{ij}$表示快遞員i是否在站點j停留以收集貨物,$y_{i}$表示快遞員i是否被分配了任務,$C_{ij}$表示在站點j收集貨物需要花費的成本。然後我們需要添加約束條件,例如:
(1)每個站點都必須要被訪問一次:
$$
\sum_{i=1}^{10}x_{ij} = 1, \forall j \in \{1,2,\cdots,20\}
$$
(2)每個快遞員只能被分配一次任務:
$$
\sum_{j=1}^{20}x_{ij} \leq 1, \forall i \in \{1,2,\cdots,10\}
$$
(3)快遞員可被分配任務的數量有限:
$$
\sum_{i=1}^{10}y_i \leq 10
$$
下面是基於CPLEX Python的配送問題實現的示例代碼:
import cplex
# 創建對象
problem = cplex.Cplex()
# 定義決策變數
num_workers = 10
num_sites = 20
x_names = ['x' + str(i) + '_' + str(j) for i in range(num_workers) for j in range(num_sites)]
y_names = ['y' + str(i) for i in range(num_workers)]
x_lb = [0] * num_workers * num_sites
x_ub = [1] * num_workers * num_sites
y_lb = [0] * num_workers
y_ub = [1] * num_workers
c = [100, 80, 80, 90, 90, 110, 60, 60, 70, 70] * 2
problem.variables.add(names=x_names + y_names, lb=x_lb + y_lb, ub=x_ub + y_ub)
# 添加約束
for j in range(num_sites):
indices = ['x' + str(i) + '_' + str(j) for i in range(num_workers)]
values = [1] * num_workers
problem.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=indices, val=values)], senses=['E'], rhs=[1])
for i in range(num_workers):
indices = ['x' + str(i) + '_' + str(j) for j in range(num_sites)]
values = [1] * num_sites
problem.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=indices, val=values)], senses=['L'], rhs=[1])
indices = ['y' + str(i) for i in range(num_workers)]
values = [1] * num_workers
problem.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=indices, val=values)], senses=['L'], rhs=[10])
# 添加目標函數
problem.objective.set_sense(problem.objective.sense.minimize)
indices = x_names
values = c
problem.objective.set_linear(zip(indices, values))
# 求解
problem.set_results_stream(None)
problem.solve()
# 輸出結果
print('Total cost:', problem.solution.get_objective_value())
for i in range(num_workers):
index = y_names[i]
value = problem.solution.get_values(i + num_workers*num_sites)
if value > 0.9:
indices = [x_names[i*num_sites + j] for j in range(num_sites)]
values = [problem.solution.get_values(i*num_sites + j) for j in range(num_sites)]
print('Worker', i, 'visits sites:', end=' ')
for j in range(num_sites):
if values[j] > 0.9:
print(j, end=' ')
print()
2. 具有多個目標的問題
很多時候,優化問題不僅有一個目標,而是有多個目標,這種問題稱為多目標優化問題(Multi-Objective Optimization Problem, MOOP)。為了解決多目標優化問題,需要將目標轉換為一個綜合目標,然後通過調整不同目標之間的權重來平衡各種目標。
CPLEX Python支持多目標線性規劃(MOLP)的求解,可以使用set_obj_fn_byname()
方法設置多個目標函數。
以下是一個簡單的MOLP實例,通過設置不同的權重來平衡兩個目標:
$$
\begin{aligned}
&\max \quad z_1 = 2x_1 + 3x_2 \\
&\max \quad z_2 = 4x_1 – 2x_2 \\
&s.t. \quad 5x_1 + 4x_2 \leq 35 \\
& \quad 2x_1 – x_2 \leq 10 \\
& \quad x_1,x_2 \geq 0 \\
\end{aligned}
$$
以下代碼演示了如何使用CPLEX Python進行MOLP建模和求解:
# 創建對象
problem = cplex.Cplex()
# 定義決策變數
problem.variables.add(names=['x1', 'x2'], lb=[0, 0])
# 添加約束
problem.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=['x1', 'x2'], val=[5, 4]),
cplex.SparsePair(ind=['x1', 'x2'], val=[2, -1])],
senses=['L', 'L'], rhs=[35, 10])
# 添加目標函數
problem.objective.set_sense(problem.objective.sense.maximize)
problem.objective.set_name(0, 'z1')
problem.objective.set_linear([('x1', 2), ('x2', 3)])
problem.objective.set_name(1, 'z2')
problem.objective.set_linear([('x1', 4), ('x2', -2)])
# 設置權重
problem.objective.set_pareto_weights([0.5, 0.5])
# 求解
problem.set_results_stream(None)
problem.solve()
# 輸出結果
for i in range(2):
print('Objective', i+1, '=', problem.solution.get_objective_value(i))
總結
CPLEX Python是一個非常強大的優化建模和求解工具,它使用Python語言可以輕鬆實現各種優化問題的建模和求解。本文介紹了CPLEX Python的基本概念、建模方法以及具體的應用示例,希望能夠幫助讀者更好地理解和應用這一工具。
原創文章,作者:HDLUS,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/372574.html