From 40d8a99eae5ed2de374f500a994efdebf4517203 Mon Sep 17 00:00:00 2001
From: Adrienucl <adrien.payen@student.uclouvain.be>
Date: Fri, 3 May 2024 12:44:15 +0200
Subject: [PATCH] update plot + validation

---
 .DS_Store               | Bin 6148 -> 6148 bytes
 markovDecision.py       |   2 +
 plot.py                 |  82 ++++++++++++++++++++++++++++++++++++++++
 strategy_comparison.png | Bin 0 -> 23502 bytes
 validation.py           |  69 +++++++++++++++++++++++++++++++++
 5 files changed, 153 insertions(+)
 create mode 100644 plot.py
 create mode 100644 strategy_comparison.png

diff --git a/.DS_Store b/.DS_Store
index 895bd9eae285819cae90199894867d4ed1ce3958..55d82a11e81b11f3bbb9102c10fed3bcce6672f9 100644
GIT binary patch
delta 162
zcmZoMXfc=|#>B)qu~2NHo+2ar#(>?7jO>$nSS)1)8FCpC8HyOP8S)v*7+e@q8Il<?
z8H#~8pCNDZ1UAXZ-7Gwu><k4AIY5z;$pLI4OpLOVJ6L)rd$Q?>@&Yv_0;Mt;Qh;;`
zR9gU>DC-Ia28Q{Y-?2$DZfr<k-ptOy&jED7W<iec%#-;=965l}42%p6ESn=l)-VGA
D$Y~@g

delta 490
zcmZuuK}!Nb6n-<SIa<*sDoGcktLdU)NvEt!w`ik+ifvcT7S|nfS2qyz;;BHCy$jJb
zs91ua|IuIRShKoC2M1=p_vU*a@69(op(hMt*cTdJ$A+mD6nfqNK#wmRMj?9+=hxy;
z0~s1n1qv<Lg)$UD1%qu0I!Iu$8-txH%PRH&N9-0}wBPV;H}uCzaLIVht=!XSQPHRZ
z06YM$Fid@q7mEO<Y81<;dzyEpuBnD82%iXZKL1RB1jsBo7q6%#nzGq63UcGr%?@do
zYRYdSD@SVClK99D)lFH|%Z;%@EtOfx*|DmZs8yg%y=08V;)EbU5|sF*c003~O(wFr
zjZQMr&S!*VVm+Jdbb=(hn%+8)s#;B_cjNH^p$Wn~WWC6PdxleA*Ag4LMs?Q-WD8sx
z@%9B5^-IjH8`sY;JTq$a&!n(h5b&(G`*<0RoIV#vPJk>B_LI&7_r=)@k!`}J!ES%&
IB=W@l0MqAv(f|Me

diff --git a/markovDecision.py b/markovDecision.py
index 6bd17bc..25c5df1 100644
--- a/markovDecision.py
+++ b/markovDecision.py
@@ -60,6 +60,7 @@ def markovDecision(layout : list, circle : bool):
 # Exemple d'utilisation de la fonction markovDecision avec les paramètres layout et circle
 layout = [0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 1, 0]
 
+"""
 # Résolution du problème avec différents modes de jeu
 result_false = markovDecision(layout, circle=False)
 print("\nWin as soon as land on or overstep the final square")
@@ -68,3 +69,4 @@ print(result_false)
 result_true = markovDecision(layout, circle=True)
 print("\nStopping on the square to win")
 print(result_true)
+"""
\ No newline at end of file
diff --git a/plot.py b/plot.py
new file mode 100644
index 0000000..c548380
--- /dev/null
+++ b/plot.py
@@ -0,0 +1,82 @@
+import matplotlib.pyplot as plt
+from validation import validation
+import numpy as np
+
+# Example layout and circle settings
+layout = [0, 0, 3, 0, 2, 0, 2, 0, 0, 0, 3, 0, 0, 1, 0]
+circle = False
+
+# Create an instance of validation
+validation_instance = validation(layout, circle)
+
+
+# Plotting function for strategy comparison
+def plot_strategy_comparison(num_games=1000):
+    strategy_costs = validation_instance.compare_strategies(num_games=num_games)
+
+    # Bar plot for strategy comparison
+    plt.figure(figsize=(10, 6))
+    plt.bar(strategy_costs.keys(), strategy_costs.values(), color=['blue', 'green', 'orange', 'red', 'purple'])
+    plt.xlabel('Strategies')
+    plt.ylabel('Average Cost')
+    plt.title('Comparison of Strategies')
+    plt.savefig('strategy_comparison.png')  # Save the plot
+    plt.show()
+
+# Plotting function for state-based average turns for all strategies on the same plot
+def plot_state_based_turns(save=True):
+    strategies = [validation_instance.optimal_strategy,
+                  validation_instance.safe_strategy,
+                  validation_instance.normal_strategy,
+                  validation_instance.risky_strategy,
+                  validation_instance.random_strategy]
+    strategy_names = ['Optimal', 'SafeDice', 'NormalDice', 'RiskyDice', 'Random']
+    
+    plt.figure(figsize=(12, 6))
+    for strategy, name in zip(strategies, strategy_names):
+        mean_turns = validation_instance.simulate_state(strategy, layout, circle)
+        plt.plot(range(len(mean_turns)), mean_turns, marker='o', linestyle='-', label=name)
+
+    plt.xlabel('State')
+    plt.ylabel('Average Turns')
+    plt.title('Average Turns per State for Different Strategies')
+    plt.grid(True)
+    plt.legend()
+
+    #if save:
+         #plt.savefig('state_based_turns_all_strategies.png')  # Save the plot
+
+    plt.show()
+
+def plot_state_based_comparison(validation_instance, num_games=1000):
+    optimal_turns, empirical_turns = validation_instance.compare_state_based_turns(num_games=num_games)
+
+    # Plotting the state-based average turns comparison
+    plt.figure(figsize=(12, 6))
+
+    # Plot optimal strategy turns
+    plt.plot(range(len(optimal_turns)), optimal_turns, marker='o', linestyle='-', label='ValueIteration')
+
+    # Plot empirical strategy turns
+    plt.plot(range(len(empirical_turns)), empirical_turns, marker='x', linestyle='-', label='Empirical')
+
+    plt.xlabel('State')
+    plt.ylabel('Average Turns')
+    plt.title('Average Turns per State - ValueIteration vs. Empirical')
+    plt.grid(True)
+    plt.legend()
+
+    plt.show()
+
+
+
+
+# Main function to generate and save plots
+if __name__ == '__main__':
+    # Example of strategy comparison plot
+    plot_strategy_comparison(num_games=1000)
+
+    # Example of state-based average turns plot for all strategies on the same plot
+    plot_state_based_turns(save=True)
+
+    plot_state_based_comparison(validation_instance, num_games=1000)
\ No newline at end of file
diff --git a/strategy_comparison.png b/strategy_comparison.png
new file mode 100644
index 0000000000000000000000000000000000000000..aefb1f990b1c89957981a9281815083011fbc9d2
GIT binary patch
literal 23502
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

literal 0
HcmV?d00001

diff --git a/validation.py b/validation.py
index 85cd231..ee6b922 100644
--- a/validation.py
+++ b/validation.py
@@ -134,6 +134,53 @@ class validation:
 
     def play_random_strategy(self, n_iterations=10000):
         return self.simulate_game(self.random_strategy, n_iterations)
+    
+    def play_empirical_strategy(self):
+        k = 0  # état initial
+        total_turns = 0
+
+        while k < len(self.layout) - 1:
+            action = self.optimal_strategy[k]  # Utiliser la stratégie empirique pour la simulation
+            action_index = int(action) - 1
+            transition_matrix = self.normal_dice  # Utiliser le dé normal pour la stratégie empirique
+
+            # Aplatir la matrice de transition en une distribution de probabilité 1D
+            flattened_probs = transition_matrix[k]
+            flattened_probs /= np.sum(flattened_probs)  # Normalisation des probabilités
+
+            # Mise à jour de l'état (k) en fonction de la distribution de probabilité aplatie
+            k = np.random.choice(len(self.layout), p=flattened_probs)
+
+            # Mise à jour du nombre de tours en fonction de l'état actuel
+            if self.layout[k] == 3 and action == 2:
+                total_turns += 1 if np.random.uniform(0, 1) < 0.5 else 2
+            elif self.layout[k] == 3 and action == 3:
+                total_turns += 2
+            else:
+                total_turns += 1
+
+        return total_turns
+
+    
+    def compare_empirical_vs_value_iteration(self, num_games=1000):
+        value_iteration_turns = self.simulate_state(self.optimal_strategy, self.layout, self.circle)
+        empirical_turns = self.simulate_state(self.optimal_strategy, self.layout, self.circle, n_iterations=num_games)
+
+        # Calculer la moyenne des tours pour chaque état
+        mean_turns_by_state = {
+            'ValueIteration': value_iteration_turns.tolist(),
+            'Empirical': empirical_turns.tolist()
+        }
+
+        return mean_turns_by_state
+    
+    def compare_state_based_turns(self, num_games=1000):
+        optimal_turns = self.simulate_state(self.optimal_strategy, self.layout, self.circle, n_iterations=num_games)
+        empirical_turns = self.simulate_state(self.optimal_strategy, self.layout, self.circle, n_iterations=num_games)
+
+        return optimal_turns, empirical_turns
+
+
 
     def compare_strategies(self, num_games=1000):
         optimal_cost = self.simulate_game(self.optimal_strategy, n_iterations=num_games)
@@ -157,6 +204,26 @@ circle = False
 validation_instance = validation(layout, circle)
 
 
+# Comparer la stratégie empirique avec la stratégie de value iteration
+turns_by_state = validation_instance.compare_empirical_vs_value_iteration(num_games=1000)
+
+# Imprimer les moyennes des tours pour chaque état
+num_states = len(layout)
+for state in range(num_states - 1):
+    print(f"État {state}:")
+    print(f"   ValueIteration - Tours moyens : {turns_by_state['ValueIteration'][state]:.2f}")
+    print(f"   Empirical - Tours moyens : {turns_by_state['Empirical'][state]:.2f}")
+
+# Exécuter la stratégie empirique une fois
+empirical_strategy_result = validation_instance.play_empirical_strategy()
+print("Coût de la stratégie empirique sur un tour :", empirical_strategy_result)
+
+# Comparer la stratégie empirique avec la stratégie de value iteration sur plusieurs jeux
+comparison_result = validation_instance.compare_empirical_vs_value_iteration(num_games=1000)
+print("Coût moyen de la stratégie de value iteration :", comparison_result['ValueIteration'])
+print("Coût moyen de la stratégie empirique :", comparison_result['Empirical'])
+"""
+
 optimal_cost = validation_instance.play_optimal_strategy(n_iterations=10000)
 print("Optimal Strategy Cost:", optimal_cost)
 
@@ -189,3 +256,5 @@ print("Mean Turns for Risky Dice Strategy:", mean_turns_risky_dice)
 random_dice_strategy = validation_instance.random_strategy
 mean_turns_random_dice = validation_instance.simulate_state(random_dice_strategy, layout, circle, n_iterations=10000)
 print("Mean Turns for Random Dice Strategy:", mean_turns_random_dice)
+"""
+
-- 
GitLab