数理最適化セミナーのご案内

3.3 実行サンプル

 開発環境に同梱されているuseSolveQP.cppsolveLPsolveQPを利用するサンプルです.線形計画問題なら,solveLPを,二次計画問題なら,solveQPを呼びます.

  • 注意:

     以降では,サンプルを用いた実行について書かれています.読み進む前に,まず,お使いのコンパイラを確認してください.サンプルは

    %NUOPT%\samples\app

    %NUOPT%はNuorium Optimizerのインストール場所,たとえばC:\Program Files\Mathematical Systems Inc\nuopt

    にある

    • app_VS2015.zip(VS2015用)
    • app_VS2017.zip(VS2017用)
    • app_VS2019.zip(VS2019用)
    • app_VS2022.zip(VS2022用)

    のうち,お使いのコンパイラに整合するものを展開してご利用ください.なお,マシンの設定によってはzipファイルのある場所に書き込み権限が無いため展開できないことがございます.この場合は書き込み権限があるフォルダに展開してください.また,コンパイラとプロジェクトが整合していない場合,リンクエラーやコンパイルエラーが生じてしまいます.

    ソリューションnuoptvcappのプロジェクト

    useSolveQP

    がこのインタフェースを用いてLP,QPを解くプログラム例です.

 useSolveQP.cppsolveLPsolveQPを利用するサンプルで,1つのmain関数のみから成ります.ロードモジュールの引数名で与えられたファイルから問題のデータを読み込み,それをsolveLPsolveQPに渡します.二次の項がなく,線形計画問題ならばsolveLPを,あればsolveQPを呼びます.以下はそのプログラムの抜粋です.

//
//  solveQPの利用例
//
#include "nuoIf.h" // 必須.
int main(int argc, char** argv)
{
  int n;
  int m;
  ifstream inputFile(argv[1]); // ロードモジュールの引数をファイル名とする
  inputFile >> n >> m ;

    (中略)

  nuoptResult* qpres = 0;
  nuoptParam myParam;
  if (nQelem || nQCelem) { // 2次の係数があるならsolveQPをコール
    qpres = solveQP(&myParam
    ,n, m
    ,minimize
    ,x0
    ,bL, bU, ibL, ibU
    ,cL, cU, icL, icU
    ,objL
    ,nAelem, irowA, jcolA, a
    ,nQelem, irowQ, jcolQ, q
    ,nQCelem, ifunQC, irowQC, jcolQC, qc
    ,ivtype, pri, dir, until, upc, dpc
  );
  } else {// 2次の係数がないのならsolveLPをコール
    qpres = solveLP(&myParam
    ,n, m
    ,minimize
    ,x0
    ,bL, bU, ibL, ibU
    ,cL, cU, icL, icU
    ,objL
    ,nAelem, irowA, jcolA, a
    ,ivtype, pri, dir, until, upc, dpc
  );
}

  if (qpres->errorCode()) {
    printf("error in solveQP code = %d, message = %s\n"
    ,qpres->errorCode(), qpres->errorMessage());
  fflush(stdout);
  exit(1);
  } else {
    printf("optimalValue = %17.10e\n", qpres->optValue());
    printf("X:\n");
    for (i = 0 ; i < n ; ++i) {
    printf("[%3d] %10.3e ", i + 1, qpres->VarVal(i));
    if ((i + 1) % 4 == 0) {
      printf("\n");
    }
  }
  printf("\n");
  printf("F:\n");
  for (i = 0; i < m; ++i) {
    printf("[%3d] %10.3e ", i + 1, qpres->FuncVal(i));
    if ((i + 1) % 4 == 0) {
      printf("\n");
    }
  }
    printf("\n");
  }

  delete qpres;
  delete [] bL;
  delete [] bU;
  delete [] ibL;
  delete [] ibU;

  (後略)
}

 次のようなナップサック問題を考えます.

\[\begin{array}{@{}ll@{}}
  \mbox{変数}               & x_{i} \in \{0,1\} \quad (i \in S) \\
  \mbox{目的関数(最大化)} & \displaystyle \sum_{i \in S} c_{i} x_{i}, \\
  \mbox{制約条件}           & \displaystyle \sum_{i \in S} a_{i}x_{i} \le b  \\
  \mbox{目的関数の係数:}   & c = ( \begin{matrix} 42 & 12 & 45 & 5 & 2 & 61 & 89 & 32 & 47 & 18 \end{matrix} ) \\
  \mbox{制約式の係数:}     & a = ( \begin{matrix} 39 & 13 & 68 & 15 & 10 & 20 & 31 & 15 & 41 & 16 \end{matrix} ) \\
  \mbox{制約式の右辺:}     & b=121
\end{array}\]

 これをsolveLPで解くには,一般の線形計画問題:

\[\begin{array}{@{}lll@{}}
  \mbox{最小化・最大化} & \displaystyle \sum_{j} c_{j} \cdot x_{j}                        & j=1,\cdots,m \\
  \mbox{条件}           & \displaystyle cu_{i} \ge \sum_{j}A_{i,j} \cdot x_{j} \ge cl_{i} & \displaystyle \begin{array}{@{}l@{}} i=1,\cdots,n \\ j=1,\cdots,m \end{array} \\
                        & bu_{j} \ge x_{j} \ge bl_{j}                                     & j=1,\cdots,m\\
                        & (x_{j} \in Z                                                    & j \in I)
\end{array}\]

の形にこの問題を表現する,すなわち

\[\begin{array}{@{}l@{}}
  c = ( \begin{matrix} 42 & 12 & 45 & 5 & 2 & 61 & 89 & 32 & 47 & 18 \end{matrix} ) \\
  Q = 0 \\
  cu = (121) \\
  cl = (-\infty) \\
  A = ( \begin{matrix} 39 & 13 & 68 & 15 & 10 & 20 & 31 & 15 & 41 & 16 \end{matrix} ) \\
  x_{j} \in \{0,1\}\mbox{(バイナリ変数)}
\end{array}\]

とすればよいことがわかります.useSolveQP.cppの入力ファイルとしてこのデータを表現したのが(Nuorium Optimizerのインストール場所)\samples\appにあるzipファイルを解凍した中にあるファイル

useSolveQP\knapsack.txt

です.


 

 

上に戻る