From 836d49aea8ed5826195ce8e51bfeeef15248ce00 Mon Sep 17 00:00:00 2001
From: webartifex <alexander@webartifex.biz>
Date: Tue, 28 Mar 2017 01:42:52 +0200
Subject: [PATCH] Add solution to fish problem

---
 fish.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 fish.py

diff --git a/fish.py b/fish.py
new file mode 100644
index 0000000..f2deb65
--- /dev/null
+++ b/fish.py
@@ -0,0 +1,100 @@
+"""
+    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 don’t 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))