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

5.13 条件式

 条件式は,添字を含む制約式および代入文において,その添字の動く範囲を制限する機能です.

 条件式は制約式や代入文の右側に記述します.この際,「,(半角コンマ)」で繋げます.書式は以下の通りです.

制約式,条件式
代入文,条件式

 次の例では,定数a[1],a[2]に-1を,a[3]に1を設定しています.

Set S = "1 2 3";
Element i(set = S);
Parameter a(index = i);
a[i] = -1, i <= 2;
a[i] = 1, i >= 3;

 条件式に使用することができる演算子は以下です.

  • 等号 ==
  • 等号付不等号 <=, >=
  • 不等号 <, >
  • 不一致 !=

 次の例では,定数asumの値を,定数a[i]の中で0より大きいものの和$\displaystyle \sum_{a_{i} > 0} a_{i}$で定めています.

Set S;
Element i(set = S);
Parameter a(index = i);
Parameter asum;
asum = sum(a[i], (i, a[i] > 0));

 不等号<, >は添字に対する集合の所属有無を表現する演算子としても使用されます.

 以下の例では,定数a[1], a[2]に-1を,a[3]に1を設定しています.

Set S;
S = "1 2 3";
Set T(superSet = S);
T = "1 2";
Element i(set = S);
Parameter a(index = i);
a[i] = -1, i < T; // iがTに含まれる場合
a[i] = 1, i > T; // iがTに含まれない場合

 条件式はsetOf関数を使って部分集合を構成する際にも使用されます.以下の例では,集合Sの中で条件a[i] > 0を満たす要素のみから,集合Tを取得しています.

Set S = "1 2 3";
Set T;
Element i(set = S);
Parameter a(index = i);
a[1] = -1;
a[2] = -1;
a[3] = 1;
T = setOf(i, a[i] > 0); // 要素3のみからなる集合Tが作成される.

 条件式同士を次のような演算子「!」,「&&」, 「,(半角コンマ)」, 「||」で連結することができます.それぞれ,not, and, and, orを意味します.次の例では,定数b[1], b[4]-1を,b[2], b[3]1を設定しています.

Set S = "1 2 3 4";
Element i(set = S);
Parameter b(index = i);
b[i] = -1, (i <= 1 || i >= 4);
b[i] = 1, (i >= 2 && i <= 3);

 最後の一行は,以下の各例のように記述する事もできます.

b[i] = 1, !(i <= 1 || i >= 4);
b[i] = 1, i >= 2, i <= 3;

 条件式に変数や整数変数を用いることはできません.次の記述は誤りです.

Variable x;
Variable y;
3 * x + 2 * y == 0, x >= 0;
3 * x + 2 * y <= 0, x < 0;

 条件式は「添字を含んだ」制約式や代入に対する機能です.添字を含んでいない場合は記述することができません.例えば以下のような記述は誤りです.

Parameter a;
Variable x;

// a が 2 以上であれば制約式 x >= 1 を成立させる
// 不正な書き方
x >= 1, a >= 2;

 上のような記述を実現したい場合はif文を使います.

Parameter a;
Variable x;

// a が 2 以上であれば制約式 x >= 1 を成立させる
if(a >= 2){
    x >= 1;
}

 

 ここからはC++SIMPLE上級者向けの説明です.

 条件式同士を演算子「&&」や「,(半角コンマ)」で連結する場合,左から順に解釈される点に注意してください.

 例として,以下のように記述されたParameter dに関してd[i + 1] == d[i]となっている箇所のみ出力することを考えます.

Set S = "1 2 3 4 5 6";
Element i(set = S);
Parameter d(index = i);
d[1] = 5;
d[2] = 4;
d[3] = 2;
d[4] = 2;
d[5] = 2;
d[6] = 3;

 以下の記述はd[i + 1] == d[i]i + 1 < Sより先に解釈されるため,範囲外であるd[7]を参照してしまうことからエラーとなります.

simple_printf("d[%d] = d[%d] = %f\n", i + 1, i, d[i], d[i + 1] == d[i], i + 1 < S);

 以下のように解釈の順番を逆にすることにより,正しく表示ができます.

simple_printf("d[%d] = d[%d] = %f\n", i + 1, i, d[i], i + 1 < S, d[i + 1] == d[i]);

 

 

上に戻る