diff options
Diffstat (limited to 'src/ch/epfl/maze/util/Statistics.java')
-rw-r--r-- | src/ch/epfl/maze/util/Statistics.java | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/ch/epfl/maze/util/Statistics.java b/src/ch/epfl/maze/util/Statistics.java new file mode 100644 index 0000000..0a4e7c6 --- /dev/null +++ b/src/ch/epfl/maze/util/Statistics.java | |||
@@ -0,0 +1,197 @@ | |||
1 | package ch.epfl.maze.util; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Collections; | ||
5 | import java.util.LinkedList; | ||
6 | import java.util.List; | ||
7 | import java.util.Map; | ||
8 | import java.util.TreeMap; | ||
9 | |||
10 | import ch.epfl.maze.physical.Animal; | ||
11 | import ch.epfl.maze.simulation.Simulation; | ||
12 | |||
13 | /** | ||
14 | * Utility class that allows to compute statistics on a list of results. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | public final class Statistics { | ||
19 | |||
20 | /* constants for the length of the distribution axis */ | ||
21 | public static final int X_LENGTH = 40; | ||
22 | public static final int Y_LENGTH = 13; | ||
23 | |||
24 | /** | ||
25 | * Returns the sum of all the numbers in results. | ||
26 | * | ||
27 | * @param results | ||
28 | * List of numbers | ||
29 | * @return The total of the list | ||
30 | */ | ||
31 | |||
32 | public static int total(List<Integer> results) { | ||
33 | int total = 0; | ||
34 | for (Integer result : results) { | ||
35 | if (result == Integer.MAX_VALUE) { | ||
36 | return Integer.MAX_VALUE; | ||
37 | } | ||
38 | total += result; | ||
39 | } | ||
40 | return total; | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Returns the mean of the numbers in results. | ||
45 | * <p> | ||
46 | * mean(<b>X</b>) = total(<b>X</b>) / N | ||
47 | * | ||
48 | * @param results | ||
49 | * List of numbers | ||
50 | * @return The mean of the results | ||
51 | */ | ||
52 | |||
53 | public static int mean(List<Integer> results) { | ||
54 | int total = total(results); | ||
55 | if (total == Integer.MAX_VALUE) { | ||
56 | return Integer.MAX_VALUE; | ||
57 | } | ||
58 | return total / results.size(); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * Returns the variance of the numbers in results. | ||
63 | * <p> | ||
64 | * var(<b>X</b>) = (<b>X</b> - mean(<b>X</b>)) / N | ||
65 | * | ||
66 | * @param results | ||
67 | * List of numbers | ||
68 | * @return The variance of the results | ||
69 | */ | ||
70 | |||
71 | public static double var(List<Integer> results) { | ||
72 | double mean = mean(results); | ||
73 | if (mean == Integer.MAX_VALUE) { | ||
74 | return Integer.MAX_VALUE; | ||
75 | } | ||
76 | double var = 0; | ||
77 | for (Integer result : results) { | ||
78 | var += (result - mean) * (result - mean); | ||
79 | } | ||
80 | return var / results.size(); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * Returns the standard deviation of the numbers in results. | ||
85 | * <p> | ||
86 | * std(<b>X</b>) = sqrt(var(<b>X</b>)) | ||
87 | * | ||
88 | * @param results | ||
89 | * List of numbers | ||
90 | * @return The variance of the results | ||
91 | */ | ||
92 | |||
93 | public static double std(List<Integer> results) { | ||
94 | return Math.sqrt(var(results)); | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * Computes distribution for each animal in simulation | ||
99 | * | ||
100 | * @param simulation | ||
101 | * Simulation to make statistics on | ||
102 | * @param numberOfSimulations | ||
103 | * The number of simulations | ||
104 | */ | ||
105 | |||
106 | public static Map<String, List<Integer>> computeStatistics( | ||
107 | Simulation simulation, int numberOfSimulations) { | ||
108 | // maps animals' names with their overall results (which are linked-list) | ||
109 | Map<String, List<Integer>> results = new TreeMap<String, List<Integer>>(); | ||
110 | |||
111 | for (Animal a : simulation.getWorld().getAnimals()) { | ||
112 | results.put(a.getClass().getSimpleName(), new LinkedList<Integer>()); | ||
113 | } | ||
114 | |||
115 | // simulates world a lot of times | ||
116 | for (int i = 0; i < numberOfSimulations; i++) { | ||
117 | |||
118 | // simulates world until the end | ||
119 | simulation.restart(); | ||
120 | while (!simulation.isOver()) { | ||
121 | simulation.move(null); | ||
122 | } | ||
123 | |||
124 | // retrieves arrival times and appends them to the results | ||
125 | Map<Integer, List<Animal>> arrivalTimes = simulation.getArrivalTimes(); | ||
126 | for (Map.Entry<Integer, List<Animal>> entry : arrivalTimes.entrySet()) { | ||
127 | for (Animal a : entry.getValue()) { | ||
128 | String animalName = a.getClass().getSimpleName(); | ||
129 | List<Integer> list = results.get(animalName); | ||
130 | list.add(entry.getKey()); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | return results; | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * Prints the distribution of all the results. | ||
140 | * | ||
141 | * @param results | ||
142 | * List of numbers | ||
143 | */ | ||
144 | |||
145 | public static void printDistribution(List<Integer> results) { | ||
146 | |||
147 | int min = results.get(0); | ||
148 | int max = results.get(results.size() - 1); | ||
149 | int length = (max - min) / X_LENGTH; | ||
150 | |||
151 | // counts number of steps inside a range | ||
152 | int lowerBound = Integer.MIN_VALUE; | ||
153 | int upperBound = min + length; | ||
154 | int index = 0; | ||
155 | List<Integer> boxPlot = new ArrayList<>(); | ||
156 | for (int i = 0; i < X_LENGTH; i++) { | ||
157 | int counter = 0; | ||
158 | |||
159 | while (index < results.size() | ||
160 | && (results.get(index) > lowerBound && results.get(index) <= upperBound)) { | ||
161 | counter++; | ||
162 | index++; | ||
163 | } | ||
164 | boxPlot.add(counter); | ||
165 | lowerBound = upperBound; | ||
166 | upperBound += length; | ||
167 | } | ||
168 | |||
169 | // draws plot on string | ||
170 | String[] printPlot = new String[Y_LENGTH]; | ||
171 | for (int i = 0; i < Y_LENGTH; i++) { | ||
172 | printPlot[i] = "| "; | ||
173 | } | ||
174 | |||
175 | int maxCount = Collections.max(boxPlot); | ||
176 | for (Integer count : boxPlot) { | ||
177 | for (int i = 0; i < Y_LENGTH; i++) { | ||
178 | if (count > (i * maxCount) / Y_LENGTH) { | ||
179 | printPlot[i] += "#"; | ||
180 | } else { | ||
181 | printPlot[i] += " "; | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | // prints plot | ||
187 | System.out.println("\n^"); | ||
188 | for (int i = Y_LENGTH - 1; i > 0; i--) { | ||
189 | System.out.println(printPlot[i]); | ||
190 | } | ||
191 | System.out.print("--"); | ||
192 | for (int i = 0; i < X_LENGTH; i++) { | ||
193 | System.out.print("-"); | ||
194 | } | ||
195 | System.out.println(">"); | ||
196 | } | ||
197 | } | ||