使用 cvxpy 时停止 GLPK 打印日志消息

Stop GLPK from printing log messages when using cvxpy

我不希望我的代码向终端打印任何内容。

现在,我运行所在的行是:

prob.solve(cp.GLPK_MI, glpk={'msg_lev': 'GLP_MSG_OFF'}, verbosity=False)

它正在显示文本:

Long-step dual simplex will be used

到目前为止,我已经查看了 this (which has been closed) and this(这似乎不起作用),但不知道传递正确的选项以使代码不打印任何内容。

如何阻止 GLPK 求解器显示文本?

如果你想要一个例子来自己测试,下面是我完整的可运行示例代码(可以通过查看来理解):

'''
Requirements.txt:
cvxopt==1.2.6
cvxpy==1.1.10
ecos==2.0.7.post1
numpy==1.20.1
osqp==0.6.2.post0
qdldl==0.1.5.post0
scipy==1.6.1
scs==2.1.2
'''
from typing import List
import math
import cvxpy as cp
import numpy as np

def solve(mech_data: List[List[float]], max_time_limit) -> List[int]:

    # number of mechanisms
    n = len(mech_data)

    # for a max time limit of 10, you need slots for each mech for time=0 and time=10
    # ...and everything in between which is 10 + 1 = 11 slots
    m = max_time_limit + 1

    log_data = []
    # log the data for the formula
    for row in mech_data:
        log_row = []
        for col in row:
            if col == 1:
                new_col = float('-inf')
            else:
                new_col = math.log(1 - col)

            log_row.append(new_col)
        log_data.append(log_row)

    log_data = np.array(log_data)

    x = cp.Variable((n, m), boolean=True)
    objective = cp.Minimize(cp.sum(cp.multiply(log_data, x)))

    # the current solver doesn't work with equalities, so each equality must be split into two inequalities.
    # see https://github.com/cvxgrp/cvxpy/issues/1112
    one_choice_per_mech_constraint = [cp.sum(x[i]) <= 1 for i in range(n)] + [cp.sum(x[i]) >= 1 for i in range(n)]

    # constrain the solution to the real time
    js = np.tile(np.array(list(range(m))), (n, 1))
    time_constraint = [cp.sum(cp.multiply(js, x)) <= max_time_limit, cp.sum(cp.multiply(js, x)) >= max_time_limit]
    constraints = one_choice_per_mech_constraint + time_constraint

    prob = cp.Problem(objective, constraints)
    # THIS SHOULD NOT PRINT ANYTHING
    prob.solve(cp.GLPK_MI, glpk={'msg_lev': 'GLP_MSG_OFF'}, verbosity=False)
    # >> Long-step dual simplex will be used
    return list(np.argmax(x.value, axis=1))

if __name__ == "__main__":
    m = 11

    # has 30% chance of working if run at least 3 times
    A_list = [0, 0, 0] + [0.3] * (m - 3)

    # has 30% chance of working if run at least 3 times
    B_list = [0, 0, 0] + [0.3] * (m - 3)

    # has 40% chance of working if run 4 times, 30% otherwise
    C_list = [0.3, 0.3, 0.3, 0.3] + [0.4] * (m - 4)

    data = [A_list, B_list, C_list]

    ans = solve(data, m-1)

不幸的是,该消息是由 GLPK 4.65 生成的,与使用的 GLP_MSG_* 选项无关。

不过,5.0 版似乎已经解决了这个问题,请参阅 this glpk-help mailing-list message from the library maintainer:

To fix the bug please replace lines 923-930 in glpk/src/draft/glpios03.c

#if 1 /* 16/III-2016 */
      if (((glp_iocp *)T->parm)->flip)
#if 0 /* 20/I-2018 */
         xprintf("WARNING: LONG-STEP DUAL SIMPLEX WILL BE USED\n");
#else
         xprintf("Long-step dual simplex will be used\n");
#endif
#endif

with the following ones:

#if 1 /* 01/III-2018 */
      if (((glp_iocp *)T->parm)->flip)
        if (T->parm->msg_lev >= GLP_MSG_ALL)
            xprintf("Long-step dual simplex will be used\n");
#endif

Please note that this change will appear in the next release of glpk.

“下一个版本”是 5.0,只有 published in December 2020 and the cvxopt wheels have not yet been updated

我已请求更新,请参阅 cvxopt wheels 项目中的 issue #8

或者,您可以 build cvxopt from source,此时您只需确保它是使用新版本构建的,或者使用生成消息的代码已禁用的 GLPK 版本构建的。