summaryrefslogtreecommitdiff
path: root/src/ch/epfl/maze/util/Statistics.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ch/epfl/maze/util/Statistics.java')
-rw-r--r--src/ch/epfl/maze/util/Statistics.java197
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 @@
1package ch.epfl.maze.util;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.Map;
8import java.util.TreeMap;
9
10import ch.epfl.maze.physical.Animal;
11import ch.epfl.maze.simulation.Simulation;
12
13/**
14 * Utility class that allows to compute statistics on a list of results.
15 *
16 */
17
18public 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}