開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Python 3.7 (プログラミング言語)
問題解決のPythonプログラミング ―数学パズルで鍛えるアルゴリズム的思考 (Srini Devadas (著)、黒川 利明 (翻訳)、オライリージャパン)の21章(質問するにもお金がかかる)、練習問題(問題3)の解答を求めてみる。
コード
Python 3
#!/usr/bin/env python3
count = 0
def compute_opt_recur(opt, left, right, prob):
global count
count += 1
if left == right:
opt[left][right] = (prob[left], left)
return
for root in range(left, right + 1):
if left <= root - 1:
compute_opt_recur(opt, left, root - 1, prob)
left_val = opt[left][root - 1]
else:
left_val = (0, None)
if root + 1 <= right:
compute_opt_recur(opt, root + 1, right, prob)
right_val = opt[root + 1][right]
else:
right_val = (0, None)
if root == left:
best_val = right_val[0]
best_root = root
elif left_val[0] + right_val[0] < best_val:
best_val = left_val[0] + right_val[0]
best_root = root
weight = sum(prob[left:right + 1])
opt[left][right] = (best_val, best_root)
def compute_opt_recur_memo(opt, left, right, prob, memo=None):
global count
count += 1
if memo is None:
memo = {}
elif (left, right) in memo:
opt[left][right] = memo[(left, right)]
return
if left == right:
opt[left][right] = (prob[left], left)
memo[(left, right)] = opt[left][right]
return
for root in range(left, right + 1):
if left <= root - 1:
if (left, root - 1) not in memo:
compute_opt_recur_memo(opt, left, root - 1, prob, memo)
memo[(left, root - 1)] = opt[left][root - 1]
left_val = memo[(left, root - 1)]
else:
left_val = (0, None)
if root + 1 <= right:
if (root + 1, right) not in memo:
compute_opt_recur_memo(opt, root + 1, right, prob, memo)
memo[(root + 1, right)] = opt[root + 1][right]
right_val = memo[(root + 1, right)]
else:
right_val = (0, None)
if root == left:
best_val = right_val[0]
best_root = root
elif left_val[0] + right_val[0] < best_val:
best_val = left_val[0] + right_val[0]
best_root = root
weight = sum(prob[left:right + 1])
memo[(left, right)] = (best_val, best_root)
opt[left][right] = memo[(left, right)]
if __name__ == '__main__':
keys = list(range(1, 8))
prob = [0.2, 0.1, 0.2, 0.0, 0.2, 0.1, 0.2]
n = len(keys)
opts = []
for func in [compute_opt_recur, compute_opt_recur_memo]:
opt = [[0 for _ in range(n)]
for _ in range(n)]
func(opt, 0, n - 1, prob)
print(f'{func.__name__}の呼び出し回数: {count}回')
count = 0
opts.append(opt)
print(opt)
print(opts[0] == opts[1])
入出力結果(cmd(コマンドプロンプト)、Terminal、Jupyter(IPython))
C:\Usrs\...>py sample3.py compute_opt_recurの呼び出し回数: 729回 compute_opt_recur_memoの呼び出し回数: 28回 [[(0.2, 0), (0.1, 0), (0.1, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0)], [0, (0.1, 1), (0.1, 2), (0.0, 1), (0.0, 1), (0.0, 1), (0.0, 1)], [0, 0, (0.2, 2), (0.0, 2), (0.0, 2), (0.0, 2), (0.0, 2)], [0, 0, 0, (0.0, 3), (0.0, 4), (0.0, 5), (0.0, 6)], [0, 0, 0, 0, (0.2, 4), (0.1, 4), (0.1, 4)], [0, 0, 0, 0, 0, (0.1, 5), (0.1, 6)], [0, 0, 0, 0, 0, 0, (0.2, 6)]] True C:\Users\...>
0 コメント:
コメントを投稿