Optimization 用于scip优化的lapack库

Optimization 用于scip优化的lapack库,optimization,lapack,scip,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
解决这个问题。我想要最小化的优化矩阵是半正定的(精确地说,它是某些变量的方差)。我在
CPLEX LP
格式的文件中遇到了问题,当我在
SCIP
中进行优化时,我得到了消息

Quadratic constraint handler does not have LAPACK for eigenvalue computation. Will assume
that matrices (with size > 2x2) are indefinite.
因此,
SCIP
在假设矩阵不确定且需要大量时间的情况下开始优化。我已经安装了
LAPACK
,甚至在
lib
文件夹中复制了
liblapack.a
文件,其中包含
SCIP
源文件和二进制文件,并重新安装了
SCIP
。但是,我一直得到上面的信息


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

目前,SCIP只能使用LAPACK-through。当使用Ipopt支持编译SCIP时,通常在非线性问题上有更好的性能,因此绝对推荐使用它。跑

make IPOPT=true

并确保事先安装了Ipopt。

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

make IPOPT=true

并确保您事先安装了Ipopt。

如果您想稍微修补一下SCIP,以便在不提供完整Ipopt的情况下使用您的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");
    }
diff--git a/src/scip/cons_quadratic.cb/src/scip/cons_quadratic.c
索引93ba359..795bade 100644
---a/src/scip/cons_.c
+++b/src/scip/cons_.c
@@ -46,7 +46,7 @@
#包括“scip/heur_trysol.h”
#包括“scip/debug.h”
#包括“nlpi/nlpi.h”
-#包括“nlpi/nlpi_ippt.h”
+/*#包括“nlpi/nlpi_ippt.h”*/
/*约束处理程序属性*/
#定义CONSHDLR_名称“二次型”
@@-4257,6+4257,71@@void checkCurvatureEasy(
*确定=假;
}
+#定义F77_FUNC(a,a)a##_
+
+/**LAPACK Fortran子程序DSYEV*/
+无效F77_FUNC(dsyev,dsyev)(
+char*jobz,/**<'N'仅计算特征值,'V'计算特征值和特征向量*/
+char*uplo,/**<'U'如果存储了A的上三角,则为'L'如果存储了A的下三角*/
+int*n,/**0:无法收敛*/
+      );
+
+/**调用Lapacks Dsyev例程来计算稠密矩阵的特征值和特征向量。
+ */
+静止的
+SCIP_RETCODE LapackDsyev(
+SCIP_Bool ComputeIgenvectors,/**<是否也应计算特征向量*/
+整数N,/**<维数*/
+SCIP_Real*a,/**<输入上的矩阵数据(大小N*N);如果ComputeIgInvectors==TRUE,则输出上的特征向量*/
+SCIP_Real*w/**<用于存储特征值的缓冲区(大小N)*/
+   )
+{
+国际信息;
+char JOBZ=ComputeIgInvectors?'V':'N';
+char UPLO='L';
+int-LDA=N;
+double*WORK=NULL;
+内部工作;
+双工作探头;
+int i;
+
+/*首先,我们要了解LWORK应该有多大*/
+LWORK=-1;
+F77_FUNC(dsyev、dsyev)(&JOBZ、&UPLO、&N、a、&LDA、w、工作探头、&LWORK和信息);
+如果(信息!=0)
+   {
+SCIPerrorMessage(“调用DSYEV.INFO=%d\n”INFO时出错);
+返回SCIP_错误;
+   }
+
+LWORK=(int)工作探头;
+断言(LWORK>0);
+
+SCIP_ALLOC(BMSallocMemoryArray(&WORK,LWORK));
+
+对于(i=0;inbilinterms;++i)
{
@@-4479,7+4544,7@@SCIP_RETCODE可检查因子(
返回SCIP_OK;
/*需要例程来计算特征值/特征向量*/
-如果(!scipipoptavailableipopt())
+如果(!TRUE)
返回SCIP_OK;
SCIP_呼叫(consdataSortQuadVarTerms(SCIP,consdata));
@@-9395,7+9460,7@@SCIP_DECL_CONSINITSOL(CONSINITSOL二次型)
SCIP_调用(SCIPcatchEvent(SCIP、SCIP_事件类型、eventhdlr、(SCIP_EVENTDATA*)conshdlr和conshdlrdata->newsoleventfilterpos));
}
-如果(nconss!=0&&!scipisipoptavailableipot()&&&!SCIPisInRestart(scip))
+如果(nconss!=0&&!TRUE&&!SCIPisInRestart(scip))
{
SCIPverbMessage(scip,scip\u VERBLEVEL\u HIGH,NULL,“二次约束处理程序执行