SlideShare a Scribd company logo
1 of 37
Download to read offline
NP問題
山登り法・焼きなまし法
中野晃作
このスライドは,東京⼀学⼀学部電⼀情報⼀学科・電気電⼀⼀学科の授業である,アルゴ
リズム(https://iis-lab.org/algorithms2020)の期末レポート課題として制作されたものを
⼀般に公開したものになります.本スライドの内容に関して,お気づきの点やさらに良く
す るためのコメントがございましたら,ぜひ本スライドの制作者にご共有ください.
P問題とNP問題
復習になりますが... 
P問題:多項式時間で答えを出す方法がある.
NP問題:多項式時間で答えを確認する方法がある.
P問題は必ずNP問題である.
NPであるが,Pではない問題は「難しい問題」=「効率的に解くアルゴリズムが知られて
いない問題」である.
NP完全とNP困難
NP完全:全てのNP問題を多項式時間帰着できるNP問題
NP困難:NP問題から多項式時間で帰着できる問題
効率的に解く方法は知られていない
→近似的なアルゴリズムで解く
最適化問題
最適化問題とは,制約条件の元で目的関数を最小にする問題.
・いくつかの最適化問題はNP困難である.
今回は効率的に解くことが困難な最適化問題の近似的な解を求める方法を紹介し
ます.
最適化問題
以下の問題を考えます.
1から26の26種類テストがあり,1日1種類,D日間実施します.以下の条件で満足度が
計算される時,満足度ができるだけ高くなるようテストの日程を決める.満足度はそれぞ
れの日の最後に計算される.
・d日目にテストiを開催する時,満足度はS(d,i)増える.
・d日目に開催されない全てのテストjに関して,最後に開催された日がd_lastとすると満
足度はc(j) × (d - d_last) 減る.
cとSは入力で与えられる.
(引用元:https://atcoder.jp/contests/intro-heuristics)
山登り法
解を探索することにより,より良い解にたどり着くことができます.
山登り法では,現在の解を少し変化させて,変化前よりも目的関数が小さく(この問題の
場合満足度が大きく)なっていた場合,その変化を適用するということを繰り返します.
山登り法
この問題の場合,例えばD=5として
① 5日分のテストの組み合わせ[1,2,3,4,5]を初期解として与えます.
② d,qをランダムに選び,d日目のテストをqに変更したときの満足度が変更前よりも改
善すれば変更を適用します.
③ ②を繰り返します.
山登り法
実装(疑似コード)
T = 初期解
山登り法
実装(疑似コード)
T = 初期解
while True:
d,q = ランダム
山登り法
実装(疑似コード)
T = 初期解
while True:
d,q = ランダム
# 満足度が改善されなかった時のために元のテストをoldとして保持
old = T[d]
山登り法
実装(疑似コード)
T = 初期解
while True:
d,q = ランダム
old = T[d]
# d日目のテストをqに更新
T[d] = q
山登り法
実装(疑似コード)
T = 初期解
while True:
…
dif_s = 満足度の差
if dif_s > 0:
# 更新
else:
# 更新しないので元に戻す
T[d] = old
山登り法
pythonでの実装例
# ライブラリのインポート
from bisect import bisect_left
import random
山登り法
pythonでの実装例
...
# 入力
D = int(input())
C = [int(c) for c in input().split()]
S = []
for _ in range(D):
s = [int(x) for x in input().split()]
S.append(s)
山登り法
pythonでの実装例
…
# 初期解.今回はランダムに初期解を設定.
T = []
for _ in range(D):
t = random.randrange(26)
T.append(t)
山登り法
pythonでの実装例
…
# 満足度計算のため,それぞれのテストの開催日を保持.
# 扱いやすくするため,開催日を-1してリストにいれる.
last_day = [[-1] for _ in range(26)]
for d in range(D):
test = T[d]
last_day[test].append(d)
for i in range(26):
last_day[i].append(D)
山登り法
pythonでの実装例
…
while True:
#ランダムな日のテストをランダムなテストに入れ替え
d = random.randrange(D)
q = random.randrange(26)
old = T[d]
T[d] = q
山登り法
pythonでの実装例
while True:
...
#日程dでの元のテストoldがなくなることによる満足度の変化を計算
l = last_day[old]
ind_old = l.index(d)
# 日程dと前後の開催日の日程間隔
dd_left = l[ind_old] - l[ind_old-1] - 1
dd_right = l[ind_old+1] - l[ind_old] - 1
dd = l[ind_old+1] - l[ind_old-1] - 1
山登り法
pythonでの実装例
while True:
...
# 日程dでの元のテストoldがなくなることによる満足度の変化を計算
…
dif_old = C[old] * (((dd_left * (dd_left + 1)) // 2) 
+ ((dd_right * (dd_right + 1)) // 2) - ((dd * (dd + 1)) // 2)) - S[d][old]
山登り法
pythonでの実装例
while True:
...
# 日程dでテストqを行うことによる満足度の変化を計算
l = last_day[q]
ind_q = bisect_left(last_day[q],d)
dd_left = d - l[ind_q-1] - 1
dd_right = l[ind_q] - d - 1
dd = l[ind_q] - l[ind_q-1] - 1
dif_q = C[q] * (((dd * (dd + 1)) // 2) 
- ((dd_left * (dd_left + 1)) // 2) - ((dd_right * (dd_right + 1)) // 2)) + S[d][q]
山登り法
pythonでの実装例
while True:
...
# 合計の満足度の変化を計算し,変更するかどうかを決定.
dif_s = dif_old + dif_q
if (dif_s > 0):
del last_day[old][ind_old]
last_day[q].insert(ind_q,d)
else:
T[d] = old
山登り法
・実装例のコード(実際には時間制限を加える)のatcoderでの提出結果
78,357,828点(あまりよくない)
・問題点
局所最適解に陥り,大域的な最適解に辿りつくことができなくなる.
山登り法
・問題点
局所最適解に陥り,大域的な最適解に辿りつくことができなくなる.
山登り法
・問題点
局所最適解に陥り,大域的な最適解に辿りつくことができなくなる.
ではどうするか?
→ ある確率で,悪くなる方向にも解を遷移させる.(焼きなまし法)
焼きなまし法
局所的な最適解を抜けられるようにするために,改悪する方向にも,ある確率で遷移さ
せる.
・どのような確率を用いるか
→時間と共に減少するような確率(終盤に改悪方向に向かう意味がない)
焼きなまし法
・時間と共に減少するような確率
ここでは,満足度が減少するときにその変更を受け入れる確率の関数として,時間と共
に減少する変数T(温度)を用い,満足度の変化をΔとして
p = exp (Δ / T)
を用いる.
焼きなまし法
・時間と共に減少するような確率
温度変数は初めは,ある程度大きく設定し,徐々に減少させます.
ここでは,初めの温度をT0として,温度T1は,
T1 = T0 ** (1 - (0から1で正規化された経過時間))
とします.
焼きなまし方
実装(疑似コード)
T = 初期解
T0 = 初期温度
while 制限時間内:
解候補を作る
if 結果がよくなる or 現在の温度に基づいた確率:
解を更新
焼きなまし法
python 実装
# ライブラリのインポート
from bisect import bisect_left
import random
import time
import math
焼きなまし法
pythonでの実装例
# 入力
# 初期解
# 開催日の保持
...
焼きなまし法
pythonでの実装例
…
# 初期温度.今回は5000とする.
T0 = 5000
# 開始時間を記録.今回は制限時間2秒.
time_start = time.perf_counter()
焼きなまし法
pythonでの実装例
…
while True:
time_now = time.perf_counter()
# 制限時間を超えないようにループを抜ける.
if time_now - time_start > 1.82:
break
#時間を0から1で正規化して温度を設定
time_n = (time_now - time_start) / 1.82
T1 = T0 ** (1 - time_n)
焼きなまし法
pythonでの実装例
while True:
…
# ランダムな日のテストをランダムに入れ替え
#日程dでの元のテストoldがなくなることによる満足度の変化を計算
# 日程dでテストqを行うことによる満足度の変化を計算
# 合計の満足度の変化を計算
…
焼きなまし法
pythonでの実装例
while True:
…
# 結果または確率関数により遷移するか決定
if (dif_s > 0) or (math.exp(dif_s / T1) > random.random()):
del last_day[old][ind_old]
last_day[q].insert(ind_q,d)
else:
T[d] = old
焼きなまし法
・実装例のコードのatcoderでの提出結果
111,583,302点(少し良い)
・山登り法で陥っていた局所的最適解からは抜けられた.
・この問題に限らず,初期温度や確率の関数を工夫することでより良い結果に到達
できる.
参考資料
・AtCoder, https://atcoder.jp/contests/intro-heuristics.
問題はAtCoder Introduction to Heuristics Contest の物を引用し,コードは解説を参
考にしました.
・授業資料

More Related Content

What's hot

卒業論文発表スライド 分割統治法の拡張
卒業論文発表スライド 分割統治法の拡張卒業論文発表スライド 分割統治法の拡張
卒業論文発表スライド 分割統治法の拡張masakazuyamanaka
 
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料Kenta Oono
 
猫でも分かるVariational AutoEncoder
猫でも分かるVariational AutoEncoder猫でも分かるVariational AutoEncoder
猫でも分かるVariational AutoEncoderSho Tatsuno
 
GPU上でのNLP向け深層学習の実装について
GPU上でのNLP向け深層学習の実装についてGPU上でのNLP向け深層学習の実装について
GPU上でのNLP向け深層学習の実装についてYuya Unno
 
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東)
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東) BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東)
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東) Mai Nishimura
 
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII
 
Delimited Dynamic Binding
Delimited Dynamic BindingDelimited Dynamic Binding
Delimited Dynamic BindingYouyou Cong
 
D言語会議#1
D言語会議#1D言語会議#1
D言語会議#19rnsr
 
定理証明支援系Coqについて
定理証明支援系Coqについて定理証明支援系Coqについて
定理証明支援系CoqについてYoshihiro Mizoguchi
 

What's hot (11)

More modern gpu
More modern gpuMore modern gpu
More modern gpu
 
卒業論文発表スライド 分割統治法の拡張
卒業論文発表スライド 分割統治法の拡張卒業論文発表スライド 分割統治法の拡張
卒業論文発表スライド 分割統治法の拡張
 
音声認識と深層学習
音声認識と深層学習音声認識と深層学習
音声認識と深層学習
 
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料
日本神経回路学会セミナー「DeepLearningを使ってみよう!」資料
 
猫でも分かるVariational AutoEncoder
猫でも分かるVariational AutoEncoder猫でも分かるVariational AutoEncoder
猫でも分かるVariational AutoEncoder
 
GPU上でのNLP向け深層学習の実装について
GPU上でのNLP向け深層学習の実装についてGPU上でのNLP向け深層学習の実装について
GPU上でのNLP向け深層学習の実装について
 
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東)
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東) BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東)
BA-Net: Dense Bundle Adjustment Network (3D勉強会@関東)
 
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
 
Delimited Dynamic Binding
Delimited Dynamic BindingDelimited Dynamic Binding
Delimited Dynamic Binding
 
D言語会議#1
D言語会議#1D言語会議#1
D言語会議#1
 
定理証明支援系Coqについて
定理証明支援系Coqについて定理証明支援系Coqについて
定理証明支援系Coqについて
 

Similar to Kosakunakano

Sec15 dynamic programming
Sec15 dynamic programmingSec15 dynamic programming
Sec15 dynamic programmingKeisuke OTAKI
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Inc.
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!bitter_fox
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208atmiya
 
ICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったかICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったかina job
 
Code iq×japanr 公開用
Code iq×japanr 公開用Code iq×japanr 公開用
Code iq×japanr 公開用Nobuaki Oshiro
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Inc.
 
動的計画法の並列化
動的計画法の並列化動的計画法の並列化
動的計画法の並列化Proktmr
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
Donutsプロコンチャレンジ 2015 解説
Donutsプロコンチャレンジ 2015 解説Donutsプロコンチャレンジ 2015 解説
Donutsプロコンチャレンジ 2015 解説kuno4n
 
ディープニューラルネット入門
ディープニューラルネット入門ディープニューラルネット入門
ディープニューラルネット入門TanUkkii
 
SGD+α: 確率的勾配降下法の現在と未来
SGD+α: 確率的勾配降下法の現在と未来SGD+α: 確率的勾配降下法の現在と未来
SGD+α: 確率的勾配降下法の現在と未来Hidekazu Oiwa
 
TSPを山登り法と焼きなまし法で解く
TSPを山登り法と焼きなまし法で解くTSPを山登り法と焼きなまし法で解く
TSPを山登り法と焼きなまし法で解くRui High
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPyShiqiao Du
 
Sanpo
SanpoSanpo
Sanpooupc
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門Shiqiao Du
 

Similar to Kosakunakano (20)

Sec15 dynamic programming
Sec15 dynamic programmingSec15 dynamic programming
Sec15 dynamic programming
 
PFI Christmas seminar 2009
PFI Christmas seminar 2009PFI Christmas seminar 2009
PFI Christmas seminar 2009
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
 
Fusion4dIntroduction
Fusion4dIntroductionFusion4dIntroduction
Fusion4dIntroduction
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208a
 
ICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったかICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったか
 
Code iq×japanr 公開用
Code iq×japanr 公開用Code iq×japanr 公開用
Code iq×japanr 公開用
 
Tokyo r27
Tokyo r27Tokyo r27
Tokyo r27
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説
 
動的計画法の並列化
動的計画法の並列化動的計画法の並列化
動的計画法の並列化
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
Donutsプロコンチャレンジ 2015 解説
Donutsプロコンチャレンジ 2015 解説Donutsプロコンチャレンジ 2015 解説
Donutsプロコンチャレンジ 2015 解説
 
ディープニューラルネット入門
ディープニューラルネット入門ディープニューラルネット入門
ディープニューラルネット入門
 
SGD+α: 確率的勾配降下法の現在と未来
SGD+α: 確率的勾配降下法の現在と未来SGD+α: 確率的勾配降下法の現在と未来
SGD+α: 確率的勾配降下法の現在と未来
 
TSPを山登り法と焼きなまし法で解く
TSPを山登り法と焼きなまし法で解くTSPを山登り法と焼きなまし法で解く
TSPを山登り法と焼きなまし法で解く
 
Coqチュートリアル
CoqチュートリアルCoqチュートリアル
Coqチュートリアル
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
Sanpo
SanpoSanpo
Sanpo
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 

Kosakunakano