【问题标题】:lapack library for scip optimization用于 scip 优化的 lapack 库
【发布时间】:2015-01-14 12:59:00
【问题描述】:

我有一个二次优化问题,我想使用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 文件夹中SCIP 源和二进制文件所在的文件夹中,然后重新安装了SCIP。但是,我不断收到上述消息。

有没有办法让SCIP 使用LAPACK 库?如果SCIP 可以算出矩阵是半正定矩阵,我相信优化会非常快。

【问题讨论】:

    标签: optimization lapack scip


    【解决方案1】:

    如果您想在不提供完整 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" 与make 一起使用。

    【讨论】:

    • 谢谢!它对我有用。我发现安装 ipopt(在 ubuntu 上)太麻烦了。唯一的变化是链接到 gfortran 库,该库使用 USRLDFLAGS="-llapack -lblas -lgfortran" 安装 scip。
    【解决方案2】:

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

    make IPOPT=true
    

    并确保您事先安装了 Ipopt。

    【讨论】:

    • 谢谢,但安装 ipopt 似乎太麻烦了。另一个解决方案对我有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2021-04-23
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多