2.14 二次割当問題
二次割当問題とは,1957年KoopmansとBeckmannにより考案された,目的関数が二次式となる割当問題です.
例題
工場1,..,5を地区I,..,Vに配置することを考えます.ただし,各工場間での物資を輸送する量,頻度などのフロー量,および各地区間の距離が,以下のように与えられているとします.
| 各工場のフロー | 各地域間の距離 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | I | II | III | IV | V | ||
| 1 | 0 | 15 | 12 | 8 | 7 | I | 0 | 4 | 7 | 6 | 10 |
| 2 | 15 | 0 | 14 | 2 | 4 | II | 4 | 0 | 2 | 5 | 4 |
| 3 | 12 | 14 | 0 | 6 | 6 | III | 7 | 2 | 0 | 8 | 7 |
| 4 | 8 | 2 | 6 | 0 | 11 | IV | 6 | 5 | 8 | 0 | 12 |
| 5 | 7 | 4 | 6 | 11 | 0 | V | 10 | 4 | 7 | 12 | 0 |
物資の輸送コストを(フロー)×(距離)で与えるとき,最もコストがかからない配置を求めなさい.
この問題は,工場間のフロー行列を,地区間の距離行列を
とすると,二次割当問題は以下の整数計画問題に定式化されます.
| 集合 | |
| 工場の集合 | |
| 地区の集合 | |
| 定数 | |
| 各工場間のフロー | |
| 各地区間の距離 | |
| 変数 | |
| 工場 |
|
| 目的関数(最小化) | |
| 輸送コストの総和 | |
| 制約条件 | |
| 各地区に割り当てられる工場は一つ | |
| 各工場に割り当てる地区は一つ | |
定式化した結果をC++SIMPLEで記述すると以下のようになります.
// 集合と添字
Set Fac;
Element i(set = Fac), j(set = Fac);
Set Loc;
Element k(set = Loc), l(set = Loc);
// パラメータ
Parameter f(index=(i,j));
Parameter d(index=(k,l));
// 変数
IntegerVariable x(index = (i, k), type = binary);
// 目的関数
Objective total_cost(type = minimize);
total_cost = sum(f[i,j]*d[k,l]*x[i,k]*x[j,l],(i,j,k,l));
// 制約条件
sum(x[i,k], k) == 1;
sum(x[i,k], i) == 1;
// 求解
options.method = "wcsp";
options.maxtim = 10;
solve();
// 結果出力
simple_printf("工場 %d を地区 %s に配置する\n", i, k, x[i,k].val == 1);以下がcsv形式の入力ファイルです.
f, 1, 2, 3, 4, 5 1, 0, 15, 12, 8, 7 2, 15, 0, 14, 2, 4 3, 12, 14, 0, 6, 6 4, 8, 2, 6, 0, 11 5, 7, 4, 6, 11, 0
d, I, II, III, IV, V I, 0, 4, 7, 6, 10 II, 4, 0, 2, 5, 4 III, 7, 2, 0, 8, 7 IV, 6, 5, 8, 0, 12 V, 10, 4, 7, 12, 0
このモデルを実行すると次のような結果が得られます.
工場 1 を地区 II に配置する 工場 2 を地区 V に配置する 工場 3 を地区 III に配置する 工場 4 を地区 IV に配置する 工場 5 を地区 I に配置する
上に戻る
