我正在使用scpsolver进行一个个人项目。该库正在生成输出,我不想看到。我实际上将其报告为错误,只是为了看看他们对此有何评论。
没有禁用输出的公开方法。 GLPKSolver类尝试使用GLPK暴露给他们的东西禁用它,但是正如下面的评论之一所述,它也不做任何事情。
我试图将System.out
和System.err
更改为空输出流,但这没有帮助,因为该库显然能够以其他方式打印到控制台。 我还是不明白它是如何工作的。
最后,我尝试使用一个setHook()
函数,但即使失败了,如底部的输出所示。
我的求解器课程
public class Solver {
private static final PrintStream out = System.out;
private static final PrintStream err = System.err;
private static final PrintStream null_stream = new PrintStream( OutputStream.nullOutputStream() );
static {
System.setOut( null_stream );
System.setErr( null_stream );
}
public static double[] solve ( double[][] A, double[] b, double[] c, double[] lb ) {
LinearProgram lp = new LinearProgram( c );
for ( int i = 0; i < b.length; i++ ) {
lp.addConstraint( new LinearEqualsConstraint( A[i], b[i], "c" + i ) );
}
lp.setLowerbound( lb );
lp.setMinProblem( false );
LinearProgramSolver solver = SolverFactory.newDefault();
double[] sol = solver.solve( lp );
System.out.flush();
System.err.flush();
System.setOut( out );
System.setErr( err );
return sol;
}
}
我重新编译的GLPKSolver.java中的代码片段重新插入库中
solver.enablePrints(false); // turn this to "false" to prevent printouts
System.out.println("Hello, world!");
solver.setHook( new GlpkHookIFC() {
@Override
public void fault ( String s ) {}
@Override
public void print ( String s ) {}
} );
System.out.println("Hi, world!");
输出:
GLPK Simplex Optimizer, v4.65
8 rows, 9 columns, 20 non-zeros
0: obj = -0.000000000e+000 inf = 1.590e+002 (2)
5: obj = -2.400000000e+003 inf = 0.000e+000 (0)
OPTIMAL LP SOLUTION FOUND
Process finished with exit code 0
尤其要注意“你好,世界!”和“嗨,世界!”都没有输出。这样做可以抑制GLPK输出的一小部分。如果我删除所有的System.*
重定向,这就是我所得到的。
Hello, world!
Hi, world!
GLPK Simplex Optimizer, v4.65
8 rows, 9 columns, 20 non-zeros
0: obj = -0.000000000e+000 inf = 1.590e+002 (2)
5: obj = -2.400000000e+003 inf = 0.000e+000 (0)
OPTIMAL LP SOLUTION FOUND
x1: 2.0
x2: 0.0
x3: 0.5
x4: 0.0
x5: 4.9
x6: 2.2
x7: 0.0
x8: 0.0
x9: 2.4
有趣的是,输出出现在 问候世界之后。
答案 0 :(得分:1)
您看到的输出是由scpsolver
调用的本机库产生的。本机库可以直接写入JVM的标准输出流,而无需通过System.out和System.err对象,并且经常这样做是因为使用本机代码中的这些对象非常不方便。
禁用输出不是一件容易的事,除非本机库本身包含执行此操作的功能。我对scpsolver或它使用的库不熟悉,但是有空的时候我可以看看。在一般情况下,您可能需要创建一个新的本机库以关闭输出。
更新:经过一番摸索,我在基础本机库中看到了there is a way to turn off terminal output:
使用GLPK API的程序员可以通过调用glp_term_out启用和禁用终端输出。挂钩函数glp_term_hook可用于拦截终端输出。还提供了更精细的谷物输出控制,但此处未涵盖-请查阅GLPK API手册。
因此,您要做的就是确保调用了这些函数。简单吧?在SCPSolver source code中,我看到there is an attempt关闭了本地库的输出:
solver.enablePrints(false); // turn this to "false" to prevent printouts
但是对C代码本机库doesn't actually do anything的此调用是因为注释了禁用打印的代码。实际上,它所做的所有事情都会泄漏一点内存:
JNIEXPORT void JNICALL
Java_org_gnu_glpk_GlpkSolver_enablePrints(JNIEnv *env, jobject obj,
jboolean enable)
{
info_t *info=malloc(sizeof(info_t));
info->env = env;
info->obj = obj;
//lib_set_fault_hook((void*)info, enable ? NULL : &_fault_hook_fn);
//lib_set_print_hook((void*)info, enable ? NULL : &_print_hook_fn);
}
可以通过在scpsolver.lpsolver.GLPKSolver的GlpkSolver solver
对象上设置一个“ hook”来禁用输出,但是通过编写代码的方式,您无法访问该对象
我建议将scpsolver.lpsolver.GLPKSolver的代码复制到您自己的项目中的类中,并将对solver.enablePrints
的调用替换为对solver.setHook
的调用。