5.4.5. Python 的SDP建模与优化¶
在本节中,我们将使用 MindOpt 的 Python API 来建模以及求解 半定规划问题示例 中的问题。
5.4.5.1. SDP示例1¶
首先,需要引入 Python 包:
26from mindoptpy import *
第一步:创建优化模型:
先建立一空的 MindOpt 模型。
31 # Step 1. Create a model.
32 model = Model()
第二步:SDP模型输入
通过 Model.addPsdVar()
,新增维度为 \(3\times3\) 的半正定矩阵变量 \(\mathbf{X}\)。
36 # Add a PSD matrix variable.
37 X = model.addPsdVar(dim=3, name="X")
输入目标函数的系数矩阵 \(\mathbf{C}\)。 并且通过 Model.setObjective()
的第一个参数,设置模型的目标函数,
以及通过第二个参数,设定优化方向为最大化。
40 C = np.array([[-3, 0, 1], [0, -2, 0], [1, 0, -3]])
41 objective = C * X
42 model.setObjective(objective, MDO.MAXIMIZE)
接着,我们输入约束系数矩阵 \(\mathbf{A}\),以及通过 Model.addConstr()
,新增模型的约束。
44 # Input the constraint.
45 A = np.array([[3, 0, 1], [0, 4, 0], [1, 0, 5]])
46 model.addConstr(A * X == 1, "c0")
第三步:求解SDP模型
模型输入后,我们便可以通过调用 Model.optimize()
求解问题。
49 model.optimize()
接下来我们可以取得最优的的目标函数值。
52 # Display objective.
53 print("Objective: " + str(objective.getValue()))
最后,我们呈现 \(\mathbf{X}\) 半正定矩阵变量的数值解。
55 # Display the solution.
56 print("X = ")
57 print(X.PsdX)
第四步:释放模型对应的资源
68 # Step 4. Free the model.
69 model.dispose()
文件链接 mdo_sdo_ex1.py 提供了完整源代码:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Semidefinite optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Maximize
12 * obj:
13 * tr(C X)
14 * Subject To
15 * c0 : tr(A X) = 1
16 * Bounds
17 * X is p.s.d.
18 *
19 * Matrix
20 * C = [ -3 0 1 ] A = [ 3 0 1 ]
21 * [ 0 -2 0 ] [ 0 4 0 ]
22 * [ 1 0 -3 ] [ 1 0 5 ]
23 * End
24 */
25 """
26from mindoptpy import *
27import numpy as np
28
29if __name__ == "__main__":
30
31 # Step 1. Create a model.
32 model = Model()
33
34 try:
35 # Step 2. Input model.
36 # Add a PSD matrix variable.
37 X = model.addPsdVar(dim=3, name="X")
38
39 # Set objective.
40 C = np.array([[-3, 0, 1], [0, -2, 0], [1, 0, -3]])
41 objective = C * X
42 model.setObjective(objective, MDO.MAXIMIZE)
43
44 # Input the constraint.
45 A = np.array([[3, 0, 1], [0, 4, 0], [1, 0, 5]])
46 model.addConstr(A * X == 1, "c0")
47
48 # Step 3. Solve the problem and display the result.
49 model.optimize()
50
51 if model.status == MDO.OPTIMAL:
52 # Display objective.
53 print("Objective: " + str(objective.getValue()))
54
55 # Display the solution.
56 print("X = ")
57 print(X.PsdX)
58 else:
59 print("No feasible solution.")
60 except MdoError as e:
61 print("Received Mindopt exception.")
62 print(" - Code : {}".format(e.errno))
63 print(" - Reason : {}".format(e.message))
64 except Exception as e:
65 print("Received exception.")
66 print(" - Reason : {}".format(e))
67 finally:
68 # Step 4. Free the model.
69 model.dispose()
5.4.5.2. SDP示例2¶
首先,需要引入 Python 包:
32from mindoptpy import *
第一步:创建MindOpt模型
先建立一空的 MindOpt 模型。
38 # Step 1. Create a model.
39 model = Model()
第二步:SDP模型输入
通过 Model.addVar()
,新增两个非负变量 \(x_0\) 和 \(x_1\)。
43 # Add nonnegative scalar variables.
44 x0 = model.addVar(lb=0.0, name="x0")
45 x1 = model.addVar(lb=0.0, name="x1")
通过 Model.addPsdVar()
,新增两个维度分别为 \(2\times 2\) 和 \(3\times 3\) 的 两个半正定矩阵变量 \(\mathbf{X}_0\) 和 \(\mathbf{X}_1\)。
47 # Add PSD matrix variables.
48 X0 = model.addPsdVar(dim = 2, name = "X0")
49 X1 = model.addPsdVar(dim = 3, name = "X1")
输入目标函数的系数矩阵 \(\mathbf{C}_0\) 和 \(\mathbf{C}_1\)。 并且通过 Model.setObjective()
的第一个参数,设置模型的目标函数,
以及通过第二个参数,设定优化方向为最大化。
51 # Set objective
52 C0 = np.array([[2, 1], [1, 2]])
53 C1 = np.array([[3, 0, 1], [0, 2, 0], [1, 0, 3]])
54 objective = C0 * X0 + C1 * X1
55 model.setObjective(objective, MDO.MAXIMIZE)
接着,我们输入第一个约束的系数矩阵 \(\mathbf{A}_{00}\),并且通过 Model.addConstr()
,新增第一个约束。
57 # Input the first constraint.
58 A00 = np.array([[3, 1], [1, 3]])
59 model.addConstr(A00 * X0 + x0 == 1, "c0")
接着,我们输入第二个约束的系数矩阵 \(\mathbf{A}_{11}\),并且通过 Model.addConstr()
,新增第一个约束。
61 # Input the second constraint.
62 A11 = np.array([[3, 0, 1], [0, 4, 0], [1, 0, 5]])
63 model.addConstr(A11 * X1 + x1 == 2, "c1")
第三步:求解SDP模型
模型输入后,我们便可以通过调用 Model.optimize()
求解问题。
66 model.optimize()
接下来我们可以取得最优的的目标函数值。
69 # Display objective.
70 print("Objective: " + str(objective.getValue()))
最后,我们呈现所有变量的数值解。
72 # Display the solution.
73 print("x0 = " + " {0:7.6f}".format(x0.X))
74 print("x1 = " + " {0:7.6f}".format(x1.X))
75 print("X0 = ")
76 print(X0.PsdX)
77 print("X1 = ")
78 print(X1.PsdX)
第四步:释放模型对应的资源
89 # Step 4. Free the model.
90 model.dispose()
文件链接 mdo_sdo_ex2.py 提供了完整源代码:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Semidefinite optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Maximize
12 * obj:
13 * tr(C0 X0) + tr(C1 X1) + 0 x0 + 0 x1
14 * Subject To
15 * c0 : tr(A00 X0) + 1 x0 = 1
16 * c1 : tr(A11 X1) + 1 x1 = 2
17 * Bounds
18 * 0 <= x0
19 * 0 <= x1
20 * X0,X1 are p.s.d.
21 *
22 * Matrix
23 * C0 = [ 2 1 ] A00 = [ 3 1 ]
24 * [ 1 2 ] [ 1 3 ]
25 *
26 * C1 = [ 3 0 1 ] A11 = [ 3 0 1 ]
27 * [ 0 2 0 ] [ 0 4 0 ]
28 * [ 1 0 3 ] [ 1 0 5 ]
29 * End
30 */
31 """
32from mindoptpy import *
33import numpy as np
34
35
36if __name__ == "__main__":
37
38 # Step 1. Create a model.
39 model = Model()
40
41 try:
42 # Step 2. Input model.
43 # Add nonnegative scalar variables.
44 x0 = model.addVar(lb=0.0, name="x0")
45 x1 = model.addVar(lb=0.0, name="x1")
46
47 # Add PSD matrix variables.
48 X0 = model.addPsdVar(dim = 2, name = "X0")
49 X1 = model.addPsdVar(dim = 3, name = "X1")
50
51 # Set objective
52 C0 = np.array([[2, 1], [1, 2]])
53 C1 = np.array([[3, 0, 1], [0, 2, 0], [1, 0, 3]])
54 objective = C0 * X0 + C1 * X1
55 model.setObjective(objective, MDO.MAXIMIZE)
56
57 # Input the first constraint.
58 A00 = np.array([[3, 1], [1, 3]])
59 model.addConstr(A00 * X0 + x0 == 1, "c0")
60
61 # Input the second constraint.
62 A11 = np.array([[3, 0, 1], [0, 4, 0], [1, 0, 5]])
63 model.addConstr(A11 * X1 + x1 == 2, "c1")
64
65 # Step 3. Solve the problem and display the result.
66 model.optimize()
67
68 if model.status == MDO.OPTIMAL:
69 # Display objective.
70 print("Objective: " + str(objective.getValue()))
71
72 # Display the solution.
73 print("x0 = " + " {0:7.6f}".format(x0.X))
74 print("x1 = " + " {0:7.6f}".format(x1.X))
75 print("X0 = ")
76 print(X0.PsdX)
77 print("X1 = ")
78 print(X1.PsdX)
79 else:
80 print("No feasible solution.")
81 except MdoError as e:
82 print("Received Mindopt exception.")
83 print(" - Code : {}".format(e.errno))
84 print(" - Reason : {}".format(e.message))
85 except Exception as e:
86 print("Received exception.")
87 print(" - Reason : {}".format(e))
88 finally:
89 # Step 4. Free the model.
90 model.dispose()