ソースを参照

update grouping

Minh Tùng Trần 3 年 前
コミット
eb8a327f5a

+ 1 - 1
code/src/main/java/analyzer/Counter.java

@@ -18,7 +18,7 @@ public class Counter {
         new Analyzer();
         countHashtag(10);
         System.out.println();
-        countClient(116000);
+        countClient(100);
         //datasetStatistics();
         //trial();
     }

+ 132 - 0
code/src/main/java/analyzer/Grouping.java

@@ -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;
+    }
+}

+ 9 - 0
code/src/main/java/analyzer/models/Client.java

@@ -7,6 +7,7 @@ import java.util.concurrent.atomic.AtomicReference;
 public class Client {
     private String id;
     private Map<Round, Integer> roundMap;
+    private Group group;
 
     public Client(String id) {
         this.id = id;
@@ -35,6 +36,14 @@ public class Client {
             this.roundMap.put(round, 1);
     }
 
+    public void setGroup(Group group) {
+        this.group = group;
+    }
+
+    public Group getGroup() {
+        return this.group;
+    }
+
     public String getRoundtoString() {
         AtomicReference<String> s = new AtomicReference<>("");
         roundMap.forEach((k, v) -> s.set(s.get() + k.getNo() + " "));

+ 45 - 0
code/src/main/java/analyzer/models/Group.java

@@ -0,0 +1,45 @@
+package analyzer.models;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+public class Group {
+    private int id;
+    private List<Client> clients = new ArrayList<>();
+    private final Map<Round, Integer> roundMap;
+
+    public Group(int id) {
+        this.id = id;
+        roundMap = new Hashtable<>();
+    }
+
+    public void addClient(Client c) {
+        if(!clients.contains(c)) {
+            this.clients.add(c);
+            c.setGroup(this);
+        }
+        c.getRounds().forEach((k, v) -> {
+            Integer value = roundMap.get(k);
+            if(value == null)
+                roundMap.put(k, v);
+            else {
+                if(v > value)
+                    roundMap.replace(k, v);
+            }
+        });
+    }
+
+    public List<Client> clients(){
+        return clients;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public Map<Round, Integer> getRounds() {
+        return roundMap;
+    }
+}