1

我有一个线性约束的二次优化问题,我想用SCIP. 我想要最小化的优化矩阵是半正定的(准确地说是某些变量的方差)。我的文件CPLEX LP格式有问题,当我优化时SCIP,我收到消息

Quadratic constraint handler does not have LAPACK for eigenvalue computation. Will assume
that matrices (with size > 2x2) are indefinite.

所以SCIP开始优化假设矩阵是不确定的并且需要大量的时间。我已经在源代码和二进制文件所在的文件夹中安装LAPACK甚至复制liblapack.a了文件并重新安装。但是,我不断收到上述消息。libSCIPSCIP

有没有办法SCIP利用LAPACK图书馆?SCIP如果能确定矩阵是半正定的,我相信优化会非常快。

4

2 回答 2

4

如果您想在不提供完整 Ipopt 的情况下稍微修补 SCIP 以使用 Lapack 库(尽管在 *nix 上构建相对容易并且可以提高性能,正如 mattmilten 指出的那样),您可以尝试以下补丁:

diff --git a/src/scip/cons_quadratic.c b/src/scip/cons_quadratic.c
index 93ba359..795bade 100644
--- a/src/scip/cons_quadratic.c
+++ b/src/scip/cons_quadratic.c
@@ -46,7 +46,7 @@
 #include "scip/heur_trysol.h"
 #include "scip/debug.h"
 #include "nlpi/nlpi.h"
-#include "nlpi/nlpi_ipopt.h"
+/*#include "nlpi/nlpi_ipopt.h" */

 /* constraint handler properties */
 #define CONSHDLR_NAME          "quadratic"
@@ -4257,6 +4257,71 @@ void checkCurvatureEasy(
       *determined = FALSE;
 }

+#define F77_FUNC(a,A) a##_
+
+   /** LAPACK Fortran subroutine DSYEV */
+   void F77_FUNC(dsyev,DSYEV)(
+      char*                 jobz,               /**< 'N' to compute eigenvalues only, 'V' to compute eigenvalues and eigenvectors */
+      char*                 uplo,               /**< 'U' if upper triangle of A is stored, 'L' if lower triangle of A is stored */
+      int*                  n,                  /**< dimension */
+      double*               A,                  /**< matrix A on entry; orthonormal eigenvectors on exit, if jobz == 'V' and info == 0; if jobz == 'N', then the matrix data is destroyed */
+      int*                  ldA,                /**< leading dimension, probably equal to n */
+      double*               W,                  /**< buffer for the eigenvalues in ascending order */
+      double*               WORK,               /**< workspace array */
+      int*                  LWORK,              /**< length of WORK; if LWORK = -1, then the optimal workspace size is calculated and returned in WORK(1) */
+      int*                  info                /**< == 0: successful exit; < 0: illegal argument at given position; > 0: failed to converge */
+      );
+
+/** Calls Lapacks Dsyev routine to compute eigenvalues and eigenvectors of a dense matrix. 
+ */
+static
+SCIP_RETCODE LapackDsyev(
+   SCIP_Bool             computeeigenvectors,/**< should also eigenvectors should be computed ? */
+   int                   N,                  /**< dimension */
+   SCIP_Real*            a,                  /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
+   SCIP_Real*            w                   /**< buffer to store eigenvalues (size N) */
+   )
+{
+   int     INFO;
+   char    JOBZ = computeeigenvectors ? 'V' : 'N';
+   char    UPLO = 'L';
+   int     LDA  = N;
+   double* WORK = NULL;
+   int     LWORK;
+   double  WORK_PROBE;
+   int     i;
+
+   /* First we find out how large LWORK should be */
+   LWORK = -1;
+   F77_FUNC(dsyev,DSYEV)(&JOBZ, &UPLO, &N, a, &LDA, w, &WORK_PROBE, &LWORK, &INFO);
+   if( INFO != 0 )
+   {
+      SCIPerrorMessage("There was an error when calling DSYEV. INFO = %d\n", INFO);
+      return SCIP_ERROR;
+   }
+
+   LWORK = (int) WORK_PROBE;
+   assert(LWORK > 0);
+
+   SCIP_ALLOC( BMSallocMemoryArray(&WORK, LWORK) );
+
+   for( i = 0; i < LWORK; ++i )
+      WORK[i] = i;
+
+   F77_FUNC(dsyev,DSYEV)(&JOBZ, &UPLO, &N, a, &LDA, w, WORK, &LWORK, &INFO);
+
+   BMSfreeMemoryArray(&WORK);
+
+   if( INFO != 0 )
+   {
+      SCIPerrorMessage("There was an error when calling DSYEV. INFO = %d\n", INFO);
+      return SCIP_ERROR;
+   }
+
+   return SCIP_OKAY;
+}
+
+
 /** checks a quadratic constraint for convexity and/or concavity */
 static
 SCIP_RETCODE checkCurvature(
@@ -4343,7 +4408,7 @@ SCIP_RETCODE checkCurvature(
       return SCIP_OKAY;
    }

-   if( SCIPisIpoptAvailableIpopt() )
+   if( TRUE )
    {
       for( i = 0; i < consdata->nbilinterms; ++i )
       {
@@ -4479,7 +4544,7 @@ SCIP_RETCODE checkFactorable(
       return SCIP_OKAY;

    /* need routine to compute eigenvalues/eigenvectors */
-   if( !SCIPisIpoptAvailableIpopt() )
+   if( !TRUE )
       return SCIP_OKAY;

    SCIP_CALL( consdataSortQuadVarTerms(scip, consdata) );
@@ -9395,7 +9460,7 @@ SCIP_DECL_CONSINITSOL(consInitsolQuadratic)
       SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_SOLFOUND, eventhdlr, (SCIP_EVENTDATA*)conshdlr, &conshdlrdata->newsoleventfilterpos) );
    }

-   if( nconss != 0 && !SCIPisIpoptAvailableIpopt() && !SCIPisInRestart(scip) )
+   if( nconss != 0 && !TRUE && !SCIPisInRestart(scip) )
    {
       SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Quadratic constraint handler does not have LAPACK for eigenvalue computation. Will assume that matrices (with size > 2x2) are indefinite.\n");
    }

与制作一起使用USRLDFLAGS="-llapack -lblas"

于 2014-11-17T15:42:28.110 回答
3

目前,SCIP 只能通过Ipopt使用 LAPACK 。SCIP 在 Ipopt 支持下编译通常会在非线性问题上具有更好的性能,因此绝对推荐。跑

make IPOPT=true

并确保您事先安装了 Ipopt。

于 2014-11-17T15:32:51.417 回答