分割問題
東京大学大学院
工学系研究科
伊庭斉志
分割問題
与えられた n 個の整数 a1,...,an を二つの集合に
分け、各々の集合内の数の和がもう一方の集合内
の数の和と等しくなるようにできるかどうかを判定
する問題
NP完全問題
分割問題
問題: {2,10,3,8,5,7,9,5,3,2} の10個の数の完璧
な分割は見つけられるか?
答え: 存在する。{2,5,3,10,7}と{2,5,3,9,8}
どちらも和は27
分割方法は23通り存在する(対称をのぞく)
分割問題
これはまれな例ではない。
1から10までの自然数10個からなる組みについ
て、完璧な分割が可能な組みは99%以上ある。
では、自然数の数が大きくなるとどうなるか?
たとえば1000個の1から10の自然数では???
とても時間がかかるので、なにか効率的なアルゴリズム
はないか?
欲張りアルゴリズム
山登り法の1つ
数を大きな順にならべる
大きき順から、その時点で和が小さいほうの
組みに割り当てていく
欲張りアルゴリズム
分割すべき集合: {19,13,9,17,6}
数を大きな順にならべる
分割すべき集合: {19,17,13,9,6}
欲張りアルゴリズム
分割すべき集合: {19,17,13,9,6}
集合1
集合2
食い違い
欲張りアルゴリズム
分割すべき集合: {17,13,9,6}
集合1
集合2
食い違い
19
19
欲張りアルゴリズム
分割すべき集合: {13,9,6}
集合1
19
集合2
17
食い違い
2
欲張りアルゴリズム
分割すべき集合: {9,6}
集合1
19
集合2
17, 13
食い違い
11
欲張りアルゴリズム
分割すべき集合: {6}
集合1
19, 9
集合2
17, 13
食い違い
2
欲張りアルゴリズム
どのくらい効率的か?
速さ
正確さ
ランダムに1万個の整数を発生させて分割可
能かを確かめてみる
成功率はどのくらいか?
もっと効率的なアルゴリズムはないか?
差分法
1982年 UCB
ナレンドラ・カーマーカー
リチャード・M・カープ
速さ
正確さ
各段階で元となる集合から数を2つ選んでは、
それらの差の絶対値で置き換える
差分法
各段階で元となる集合から数を2つ選んでは、
それらの差の絶対値で置き換える
選んだ2つの整数のどちらがどの組に行くかは決
めない
とりあえず別々の組に行くことのみ決める
この作業を残る数が1個になるまで続けると、残っ
た数がその分割による食い違いになる
その後で作業を逆にたどり分割を再構成する
差分法
分割すべき集合: {19,17,13,9,6}
差
集合1
集合2
食い違い
2
0
差分法
分割すべき集合: {13,9,6,2}
差
集合1
集合2
食い違い
4
0
差分法
分割すべき集合: {6,4,2}
差
集合1
集合2
食い違い
2
0
差分法
分割すべき集合: {2,2}
差
集合1
集合2
食い違い
0
0
差分法
分割すべき集合: {0}
差
集合1
集合2
食い違い
0
差分法 (逆にたどる)
分割すべき集合: {0}
差
集合1
集合2
0
食い違い
0
差分法 (逆にたどる)
分割すべき集合: {2,2}
差
0
集合1
集合2
2
2
食い違い
0
差分法 (逆にたどる)
分割すべき集合: {6,4,2}
差
2
集合1
集合2
4,2
6
食い違い
0
差分法 (逆にたどる)
分割すべき集合: {13,9,6,2}
差
4
集合1
集合2
13,2
9,6
食い違い
0
差分法 (逆にたどる)
分割すべき集合: {19,17,13,9,6}
差
2
集合1
集合2
13,19
17,9,6
食い違い
0
差分法
差分法は本当にいいか?
1から1000までの整数
{771,121,281,854,885,734,468,1003,83,62}
この10個の数は完璧に分割できる
欲張りアルゴリズムではうまくいかない(差は32)
差分法でも駄目(差は26)
どうやればうまくいくか?
Flyodの問題 レポート課題
1から50までの整数がある.
これをAとBの2つの集合にわけ,それぞれに
おいて平方根をとって和をとる.
この和がもっとも近くなるようにAとBを決めよ.
どうやればうまくいくか?
Flyodの問題 レポート課題
例1:Aを奇数,Bを偶数の集合
差の絶対値=&3.173106321065504
例2:Aを3の倍数,Bをその他の集合
差の絶対値=&84.989984837088443
Flyodの問題 レポート課題
全探索の計算量
知られている最良解の1つ
差の絶対値=10^-12
整数を含めて15桁が一致
Knuthのヒューリスティックス
レポート課題の1つ
欲張りはどうなのか?
差分法は本当にいいのか?
他にいい方法がないのだろうか?
ヒューリスティック、GA
どのようにして確かめたらいいだろうか?
ランダムに問題を生成していろいろな方法で試す
意地悪な問題をわざと作ってみる
ソートの分は損していないか?
© Copyright 2026 ExpyDoc