最適化セミナーのご案内

4.2.1 モデル兼ドライバの記述(UNIX)

 次は,SIMPLEの記述を利用して問題を入力,求解,解の出力を行う手続き(サンプルディレクトリ内のMIP.cc)です.

#include "simple.h"

//
// ナップサック問題
//
// 引数ならびと関数名は任意

int MIPsolve(int narg,double* aarg,double barg,double* carg
        ,double* xarg,double* farg)
{
  //
  // システムの初期化(これまで定義したシステムをクリア,以降SIMPLEの記述)
  //
  SimpleInitialize();

    Set S;
    Element i(set=S);

    IntegerVariable x(name="決定ベクトル"
                  ,index=i,type=binary); // 整数変数
    Parameter c(name="価値",index=i);
    Parameter a(name="重量",index=i);
    Parameter b(name="許容重量");
    Objective obj(name="総価値",type=maximize);

    // 引数からデータを設定
    // (Numerical Optimizer/SIMPLEマニュアルを参照)
    a.readD(narg,aarg);
    b = barg;
    c.readD(narg,carg);

    0 <= x[i] <= 1;

    sum(a[i]*x[i],i) <= b;     // 制約条件
    obj = sum(c[i]*x[i],i);    // 目的関数

    // Numerical Optimizerからの最適化結果ファイル.solの
    // 名前の設定
    //    options.outfilename = "nuoptout";
    // .solのファイル出力を抑制する場合には次のように書く
    options.outfilename = "_NULL_";
    // 出力を抑制する
    options.outputMode = "silent";

    // 最適化の実行
    solve();

    // xの内容をC++の配列にダンプ
    // (Numerical Optimizer/SIMPLEマニュアルを参照)
    int lenx;
    int* indx;
    double* valx;
    x[i].val.dump(lenx,indx,valx);

    if ( lenx != narg) {
      return 99; // x[i]の実際の長さがnargと異なる(データに矛盾あり)
    }

    // 引数に設定
    int it;
    for ( it = 0 ; it < lenx ; ++it ) {
      xarg[indx[it]-1] = valx[it];
        // indx[it]は1,2, ... nargなので,1を引く
    }

    // 目的関数値の設定
    *farg = result.optValue;

    // indx,valxはdump内部で独自にallocateされるのでfreeしておく.
    delete [] indx;
    delete [] valx;

    // Numerical Optimizerのエラーコードを返す.
    return result.errorCode;
}

 この手続き(MIPsolve)は呼ばれるたびに,新しいデータをもとにシステムを作成し直すことを前提としておりますので,手続きが始まるとき定義したモデルの内容をクリアする必要があります.そうするにはここで行っているように最初にSimpleInitialize()をコールします.


 

 

上に戻る