|
@@ -0,0 +1,132 @@
|
|
|
+package analyzer;
|
|
|
+
|
|
|
+import analyzer.models.Client;
|
|
|
+import analyzer.models.Group;
|
|
|
+import analyzer.models.Round;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+public class Grouping {
|
|
|
+
|
|
|
+ private static List<Client> clients;
|
|
|
+ private static List<Round> rounds;
|
|
|
+ private static List<Group> groups;
|
|
|
+
|
|
|
+ private static final int threshold = 20;
|
|
|
+ private static final int learningRounds = 20;
|
|
|
+
|
|
|
+ public static void main(String[] args) throws InterruptedException {
|
|
|
+ Analyzer a = new Analyzer();
|
|
|
+ clients = new ArrayList<>();
|
|
|
+ groups = new ArrayList<>();
|
|
|
+ rounds = new ArrayList<>(ServerLogParser.rounds.values());
|
|
|
+ rounds.sort(Comparator.comparingInt(Round::getNo));
|
|
|
+ rounds = rounds.subList(0, learningRounds);
|
|
|
+ run();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void run(){
|
|
|
+ System.out.println("threshold: " + threshold);
|
|
|
+ System.out.println("learningRounds: " + learningRounds);
|
|
|
+ for(int i = 1; i <ServerLogParser.rounds.values().size(); i++) {
|
|
|
+ Round r = ServerLogParser.rounds.get(i);
|
|
|
+ rounds.add(r);
|
|
|
+ ClientLogParser.clients.values().forEach(c -> {
|
|
|
+ if(c.getRounds().containsKey(r))
|
|
|
+ if(c.getTotalPosts() >= 100 && !clients.contains(c))
|
|
|
+ clients.add(c);
|
|
|
+ });
|
|
|
+ if(i >= learningRounds) {
|
|
|
+ group(i);
|
|
|
+ int progress = (int) (((float) i /(float) ServerLogParser.rounds.values().size()) * 100F);
|
|
|
+ System.out.print("\r");
|
|
|
+ System.out.print(progress + " %");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println();
|
|
|
+ System.out.println("Group no: " + groups.size());
|
|
|
+ int ungrouped = 0;
|
|
|
+ for (Client c : clients) {
|
|
|
+ if(c.getGroup() == null)
|
|
|
+ ungrouped++;
|
|
|
+ }
|
|
|
+ System.out.println("ungrouped: " + ungrouped);
|
|
|
+ int sumSize = 0;
|
|
|
+ for(Group g : groups) {
|
|
|
+ sumSize += g.clients().size();
|
|
|
+ System.out.print(g.clients().size() + ",");
|
|
|
+ }
|
|
|
+ System.out.println();
|
|
|
+ System.out.println("Avg Size of Groups: " + sumSize/groups.size());
|
|
|
+ System.out.println("Avg No of Cover Messages: " + coverMessagesCount()/(clients.size() - ungrouped));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void group(int currentRound) {
|
|
|
+ for(Client c1 : clients) {
|
|
|
+ for(Client c2 : clients) {
|
|
|
+ if(c1.equals(c2) || c2.getGroup() != null)
|
|
|
+ continue;
|
|
|
+ else {
|
|
|
+ int distance = euclideanDistance(c1, c2, currentRound);
|
|
|
+ Group group = c1.getGroup();
|
|
|
+ if(group == null && distance < threshold) {
|
|
|
+ group = new Group(0);
|
|
|
+ group.addClient(c1);
|
|
|
+ group.addClient(c2);
|
|
|
+ groups.add(group);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if(group != null && suitable(c2, group, currentRound))
|
|
|
+ group.addClient(c2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean suitable(Client client, Group group, int currentRound) {
|
|
|
+ int sum = 0;
|
|
|
+ for(Client c : group.clients()) {
|
|
|
+ if(euclideanDistance(c, client, currentRound) >= threshold)
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int coverMessagesCount() {
|
|
|
+ int sum = 0;
|
|
|
+ for(Group g : groups) {
|
|
|
+ for(Client c : g.clients())
|
|
|
+ for(Round r : ServerLogParser.rounds.values()) {
|
|
|
+ Integer value1 = g.getRounds().get(r);
|
|
|
+ Integer value2 = c.getRounds().get(r);
|
|
|
+ if(value1 == null)
|
|
|
+ value1 = 0;
|
|
|
+ if(value2 == null)
|
|
|
+ value2 = 0;
|
|
|
+ int diff = value1 - value2;
|
|
|
+ sum += diff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sum;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int euclideanDistance(Client c1, Client c2, int currentRound) {
|
|
|
+ int sum = 0;
|
|
|
+ List<Round> subset = rounds.subList(currentRound - learningRounds, currentRound + 1);
|
|
|
+
|
|
|
+ for(Round r : subset) {
|
|
|
+ Integer value1 = c1.getRounds().get(r);
|
|
|
+ Integer value2 = c2.getRounds().get(r);
|
|
|
+ if(value1 == null)
|
|
|
+ value1 = 0;
|
|
|
+ if(value2 == null)
|
|
|
+ value2 = 0;
|
|
|
+ int diff = Math.abs(value1 - value2);
|
|
|
+ sum += diff;
|
|
|
+ }
|
|
|
+ return sum;
|
|
|
+ }
|
|
|
+}
|