最適化セミナーのご案内

5.2.3 ナップサック問題のモデル(C++の配列からのデータ設定)(UNIX)

 useClass.ccではもうひとつknapsack.smpというモデルを利用していますが,このモデルのデータはC++の配列からデータを入力しています.その場合にはモデルの記述に変更が必要です.具体的には外部入力とするパラメータの宣言部分にrequiredというキーワードを追加します.

//
// ナップサック問題
//

    Set S;
    Element i(set=S);
    IntegerVariable x(index=i,type=binary); // 整数変数
    Parameter c(index=i,required);
    Parameter a(index=i,required);
    Parameter b(required);
    Objective obj(type=maximize);

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

 次はuseClass.ccの中でknapsack.smpに対するデータを設定している部分です.requiredをつけて宣言したオブジェクトを含む.smpに対応するクラス(ここではSystem_knapsack)は,requiredをつけて宣言したParameterを順に与えて宣言する必要があります.そうして与えられたParameterが対応するオブジェクトの初期値になります.

// knapsack.smpの初期化用のデータの宣言
Set S;
Parameter a(index=S);
Parameter c(index=S);
Parameter b;

// データをC++側から与える.
double cary[10] = { 42, 12, 45 , 5  , 2, 61, 89 , 32 , 47, 18};
double aary[10] = { 39, 13, 68 , 15 , 10 , 20 , 31 , 15 , 41 , 16};

// C++の配列を初期化用のデータに与える.
  b = 121; // スカラはそのまま代入
  c.readD(10,cary); // 配列はreadDを用いる.
  a.readD(10,aary); // 配列はreadDを用いる.

  System_knapsack knap(c,a,b); // knapsack 問題の求解

  double* knapx;
  knap.x.val.dump(len,ind,knapx); // knapsack問題のxをknapxにダンプ

// 表示
  printf("x(knapsack):\n");
  for ( i = 0 ; i < len ; ++i ) {
      printf("[%3d] %10.3e ",ind[i],knapx[i]);
      if ( (i+1) % 4 == 0 ) {
       printf("\n");
      }
  }
  printf("\n");
  
  delete [] ind;

 上の例では,まず,useClass.ccの中でcabを宣言して,readDや代入によってデータの内容を設定,続いてknapの宣言に与えています.こうすることによってモデル中のcabuseClass.ccの中のcabの値が与えられます.useClass.ccのなかのcabknapsack.smpの中のcabとはここでは同じ名前ですが,必ずしもそうである必要はありません.


 

 

上に戻る