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 clients; private static List rounds; private static List 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 { 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 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; } }