在python中使用不同的求解器优化线性系统的不同结果

时间:2019-03-29 14:40:10

标签: python optimization scipy linear-programming lpsolve

我有一个由成对网络组成的线性系统,我想使用python中的求解器来优化最小值。以下数据总结了该系统源自小型网络的示例

obj_func
{('1', '2'): [1, 1, 1],
 ('2', '3'): [1, 1, 1, 2, 1, 0],
 ('2', '4'): [1, 1, 1, 2, 0, 1],
 ('3', '4'): [0, 1, 1, 1]}

rhs
{('1', '2'): [0.3333487586477922, 0.3333487586477922, 0.3333024827044157, 1.0],
 ('2', '3'): [0.5, 0.5, 0.3333487586477922, 0.3333487586477922, 0.3333024827044157],
 ('2', '4'): [0.49996529223940045, 0.5000347077605996, 0.3333487586477922, 0.3333487586477922, 0.3333024827044157],
 ('3', '4'): [0.49996529223940045, 0.5000347077605996, 0.5, 0.5]}

constraints
defaultdict(<class 'list'>,
  {('1', '2'): [[[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1]]],
   ('2', '3'): [[[1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0], [0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1]]],
   ('2', '4'): [[[1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0], [0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1]]],
   ('3', '4'): [[[1, 1, 0, 0], [0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0, 1]]]})

以前,我在R中使用lpSolve进行了优化,但是出于编程原因,我更改为python3并使用了Scipy.optimize.linprog()。现在,我使用lpsolve55中的lp_solve,但结果与scipy.optimize.linprog()LpSolveR的结果不同!

以下是使用scipy.optimize.linprog()

的代码
from scipy.optimize import linprog

min_for_pairs = []
for pair in list(network.edges()):
  A = np.reshape(constraints[pair], (-1, len(obj_func[pair]))) 
  res = linprog(obj_func[pair], A_eq=A, b_eq=rhs[pair], method='interior-point', options={'presolve': True})
  min_for_pairs.append(res.fun)

min_for_pairs
[1.0, 0.6666975173156104, 0.666651241372254, 0.5000347083535648]

,而这个使用lp_solve

from lpsolve55 import *
from lp_maker import *
from lp_solve import *

min_for_pairs = []
for pair in list(network.edges()):
  A = np.reshape(constraints[pair], (-1, len(obj_func[pair])))
  sense_equality = [0] * len(A)
  lp = lp_maker(obj_func[pair], A , rhs[pair], sense_equality)
  solvestat = lpsolve('solve', lp)
  obj = lpsolve('get_objective', lp)
  min_for_pairs.append(obj)

min_for_pairs
[1.0, 1.3333487586477921, 1.3333487586477921, 1.0]

我想知道:

1)我的代码有什么问题,使我得到不同的结果?这是正常的,因为lp_solve找不到最佳选择吗?

2)我从scipy更改为lpsolve55,因为在大型网络上运行时速度太慢。例如,我使用scipy来获取目标函数的最小值,该目标函数是从少于16000对的小型网络派生而来的,花费了6个小时以上!通常,lp_solvelp_maker是否适用于大型系统?还是我需要换一个求解器?

1 个答案:

答案 0 :(得分:0)

scipy is minimizing是您的目标。

Whereas the top level linprog module expects a problem of form:

Minimize:

c @ x
Subject to:

A_ub @ x <= b_ub
A_eq @ x == b_eq
 lb <= x <= ub
where lb = 0 and ub = None unless set in bounds.

lp_maker maximizes是目标。

lp_maker.py
This script is analog to the lp_solve script and also uses the API to create a higher-level function called lp_maker. This function accepts as arguments some matrices and options to create an lp model. Note that this scripts only creates a model and returns a handle. Type help(lp_maker) or just lp_maker() to see its usage:

   LP_MAKER  Makes mixed integer linear programming problems.

   SYNOPSIS: lp_handle = lp_maker(f,a,b,e,vlb,vub,xint,scalemode,setminim)
      make the MILP problem
        max v = f'*x
          a*x <> b
            vlb <= x <= vub
            x(int) are integer

   ARGUMENTS: The first four arguments are required:
            f: n vector of coefficients for a linear objective function.
            a: m by n matrix representing linear constraints.
            b: m vector of right sides for the inequality constraints.
            e: m vector that determines the sense of the inequalities:
                      e(i) < 0  ==> Less Than
                      e(i) = 0  ==> Equals
                      e(i) > 0  ==> Greater Than
          vlb: n vector of non-negative lower bounds. If empty or omitted,
               then the lower bounds are set to zero.
          vub: n vector of upper bounds. May be omitted or empty.
         xint: vector of integer variables. May be omitted or empty.
    scalemode: Autoscale flag. Off when 0 or omitted.
     setminim: Set maximum lp when this flag equals 0 or omitted.

   OUTPUT: lp_handle is an integer handle to the lp created.