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 |
物資の輸送コストを(フロー)×(距離)で与えるとき,最もコストがかからない配置を求めなさい.
この問題は,工場間のフロー行列を,地区間の距離行列をとすると,二次割当問題は以下の整数計画問題に定式化されます.
集合 | |
工場の集合 | |
地区の集合 | |
定数 | |
各工場間のフロー | |
各地区間の距離 | |
変数 | |
工場を地区に配置する場合1それ以外は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 に配置する
上に戻る