用于scip优化的lapack库

时间:2014-11-17 15:10:24

标签: optimization lapack scip

我有一个二次优化问题,我想用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文件复制到lib源文件夹和{2}源文件夹中并重新安装SCIP。但是,我一直收到上述信息。

有没有办法让SCIP使用SCIP库?我相信如果LAPACK能够发现矩阵是半正定的,那么优化会非常快。

2 个答案:

答案 0 :(得分:4)

如果你想修补一下SCIP有点使用你的Lapack lib而不提供完整的Ipopt(虽然它相对容易构建在* 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"与make。

一起使用

答案 1 :(得分:3)

目前,SCIP只能通过Ipopt使用LAPACK。当SCIP使用Ipopt支持进行编译时,非线性问题通常会有更好的表现,因此绝对值得推荐。运行

make IPOPT=true

并确保事先安装了Ipopt。