ortools中的迭代算法pdlp
- ortools 中提供了一个文档介绍快速具体算法 https://developers.google.cn/optimization/lp/lp_advanced?hl=en
其中实现了一个迭代法 PDLP, 对于低精度,以及给定初值的情况应该比较有利。
文档没有提供例子, 但代码路中有例子:
-
Python版 https://github.com/google/or-tools/blob/main/ortools/pdlp/samples/simple_pdlp_program.py
-
c 版本 https://github.com/google/or-tools/blob/main/ortools/pdlp/samples/simple_pdlp_program.cc
-
java 版 或许可以参考实现. java 直接调用
MPSolver solver = MPSolver.createSolver("PDLP");
-
通用用法(Java可用) https://groups.google.com/g/or-tools-discuss/c/EulhYdMudBw
- 可以控制迭代精度和步数
MPSolver solver = MPSolver.createSolver("PDLP"); String pdlp_params_str = "termination_criteria: { iteration_limit: 500 "+ "simple_optimality_criteria {eps_optimal_absolute: 1e-4 eps_optimal_relative: 1e-4 }}"; solver.setSolverSpecificParametersAsString(pdlp_params_str);
-
python 专用的调用方法
-
https://github.com/google/or-tools/blob/stable/ortools/pdlp/samples/simple_pdlp_program.py
-
https://github.com/google/or-tools/blob/stable/ortools/pdlp/python/pywrap_pdlp_test.py
-
这个方法,有几个好处:
- 可以控制迭代精度和步数,
- 可以传入初始值 (注意需要提供对偶变量、原变量)
- 以矩阵形式更高效的构造数据
def tiny_lp(): """Returns a small test LP. The LP: min 5 x_1 + 2 x_2 + x_3 + x_4 - 14 s.t. 2 x_1 + x_2 + x_3 + 2 x_4 = 12 x_1 + x_3 >= 7 x_3 - x_4 >= 1 0 <= x_1 <= 2 0 <= x_2 <= 4 0 <= x_3 <= 6 0 <= x_4 <= 3 Optimum solutions: Primal: x_1 = 1, x_2 = 0, x_3 = 6, x_4 = 2. Value: 5 + 0 + 6 + 2 - 14 = -1. Dual: [0.5, 4.0, 0.0] Value: 6 + 28 - 3.5*6 - 14 = -1 Reduced costs: [0.0, 1.5, -3.5, 0.0] """ qp = pywrap_pdlp.QuadraticProgram() qp.objective_offset = -14 qp.objective_vector = [5, 2, 1, 1] qp.constraint_lower_bounds = [12, 7, 1] qp.constraint_upper_bounds = [12, np.inf, np.inf] qp.variable_lower_bounds = np.zeros(4) qp.variable_upper_bounds = [2, 4, 6, 3] constraint_matrix = np.array([[2, 1, 1, 2], [1, 0, 1, 0], [0, 0, 1, -1]]) qp.constraint_matrix = scipy.sparse.csr_matrix(constraint_matrix) return qp def test_starting_point(self): params = solvers_pb2.PrimalDualHybridGradientParams() opt_criteria = params.termination_criteria.simple_optimality_criteria opt_criteria.eps_optimal_relative = 0.0 opt_criteria.eps_optimal_absolute = 1.0e-10 params.l_inf_ruiz_iterations = 0 params.l2_norm_rescaling = False start = pywrap_pdlp.PrimalAndDualSolution() start.primal_solution = [1.0, 0.0, 6.0, 2.0] start.dual_solution = [0.5, 4.0, 0.0] result = pywrap_pdlp.primal_dual_hybrid_gradient( tiny_lp(), params.SerializeToString(), initial_solution=start) solve_log = solve_log_pb2.SolveLog.FromString(result.solve_log_str) self.assertEqual(solve_log.termination_reason, solve_log_pb2.TERMINATION_REASON_OPTIMAL) self.assertEqual(solve_log.iteration_count, 0)
-
--- 她说, 她是仙,她不是神