1
0
Fork 0
whu-dynamic-programming/fish.py

101 lines
3 KiB
Python
Raw Permalink Normal View History

2017-03-28 01:42:52 +02:00
"""
fish.py
~~~~~~~
This module solves the fish homework problem.
Run with "python fish.py"
Description:
Every year (for 3 years) we decide whether to fish in a lake or not.
If we fish, the population of fish in the lake remains the same.
If we dont fish, the population of fish in the lake doubles.
Years of experience tell us that our profit is exactly 70% of the
number of fish in the lake if we fish.
If there are 10 fish in the lake, we make $7.
The interest rate is 25%
We need a contingency plan: no matter what situation we find
ourselves in, we need to have an optimal strategy.
We could try every strategy, but that quickly gets out of control:
there are too many possibilities!
Output:
{0: {10: {'fish': False, 'value': 32.25600000000001}},
1: {10: {'fish': False, 'value': 20.160000000000004},
20: {'fish': False, 'value': 40.32000000000001}},
2: {10: {'fish': True, 'value': 12.600000000000001},
20: {'fish': True, 'value': 25.200000000000003},
40: {'fish': True, 'value': 50.400000000000006}},
3: {10: {'fish': True, 'value': 7.0},
20: {'fish': True, 'value': 14.0},
40: {'fish': True, 'value': 28.0},
80: {'fish': True, 'value': 56.0}},
4: {10: {'value': 0},
20: {'value': 0},
40: {'value': 0},
80: {'value': 0},
160: {'value': 0}}}
Optimal strategy: do not fish -> do not fish -> fish -> fish
"""
from copy import deepcopy
from pprint import pprint
# Problem parameters
initial_population = 10
growth_factor = 2
profit_rate = 0.7
interest_rate = 0.25
final_value = 0
n_periods = 4
# Initialize data structures to keep track of calculations
tree = {
0: {
initial_population: {},
},
}
max_population = initial_population
# Construct the tree by forward calculation
for i in range(n_periods):
tree[i+1] = deepcopy(tree[i])
max_population *= growth_factor
tree[i+1][max_population] = {}
# Set the values for all nodes in the last period to 0
for key in tree[n_periods].keys():
tree[n_periods][key]['value'] = 0
# Value the tree by backward induction
for i in reversed(range(n_periods)):
for key in tree[i].keys():
fish = profit_rate * key + (1 / (1 + interest_rate)) * tree[i+1][key]['value']
no_fish = (1 / (1 + interest_rate)) * tree[i+1][key * growth_factor]['value']
tree[i][key]['value'] = max(fish, no_fish)
if fish > no_fish:
tree[i][key]['fish'] = True
else:
tree[i][key]['fish'] = False
# Print the decision rule
result = []
optimal_population = initial_population
for i in range(n_periods):
if tree[i][optimal_population]['fish']:
result.append('fish')
else:
result.append('do not fish')
optimal_population *= growth_factor
pprint(tree)
print('Optimal strategy: ' + ' -> '.join(result))