aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java
blob: d37910efe81a8bfce3d8d4bff663bea53156ad19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package edu.brown.cs.student.term.hub;

import edu.brown.cs.student.term.DatabaseQuerier;
import edu.brown.cs.student.term.profit.ProfitCalculation;

import java.time.Instant;
import java.sql.Date;
import java.util.*;

public class SuspicionRanker {

  DatabaseQuerier querier;

  public SuspicionRanker(DatabaseQuerier db) {
    this.querier = db;
  }

  private <K, V extends Comparable<V>> V getMaxOfMap(Map<K, V> map) {
    //Map.Entry<K, V> maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue());
    Collection<V> values = map.values();
    return Collections.max(map.values());
  }

  private <K, V extends Comparable<V>> V getMinOfMap(Map<K, V> map) {
    Map.Entry<K, V> maxEntry = Collections.min(map.entrySet(), Map.Entry.comparingByValue());
    return maxEntry.getValue();
  }

  private class SuspicionComparator implements Comparator<Holder> {
    @Override
    public int compare(Holder o1, Holder o2) {
      if (o1.getSuspicionScore() > o2.getSuspicionScore()) {
        return -1;
      } else if (o1.getSuspicionScore() < o2.getSuspicionScore()) {
        return 1;
      } else {
        return 0;
      }
    }
  }

  /**
   *
   * @param start
   * @param end
   * @return
   */
  public List<Holder> getSuspicionScoreList(Instant start, Instant end) {
    PriorityQueue<Holder> orderedSuspicion = new PriorityQueue<>(new SuspicionComparator());
    List<Holder> suspicionList = new ArrayList<>();
    try {
      LinkMapper lm = new LinkMapper(querier);
      HubSearch hub = new HubSearch(lm);
      Map<Holder, Double> holderToHubScore = hub.runHubSearch(start, end);

      ProfitCalculation pc = new ProfitCalculation(DatabaseQuerier.getConn(), "",
          new Date(start.toEpochMilli()),
          new Date(end.toEpochMilli()));

      Map<Integer, Double> profitMap = pc.getProfitMap();
      System.out.println(profitMap);

      //if the maps are empty, we abort because we have entirely incomplete data
      if(profitMap.isEmpty() || holderToHubScore.isEmpty()){
        return new ArrayList<>();
      }

      double profitMax = getMaxOfMap(profitMap);

      //if all of our values are negative, we need to flip sides so that the
      //biggest loser doesn't end up being the most suspicious person*/
     if(profitMax <= 0) {
        profitMax = Math.abs(getMinOfMap(profitMap));
     }


     //if both the min we found and max we found are 0, then we have
     //the special case where all the values are 0, in which case we
     //need to avoid dividing by 0

     if(profitMax == 0){
       profitMax = 1;
     }


      double hubMax = getMaxOfMap(holderToHubScore);

      for (Holder guy : holderToHubScore.keySet()) {
        double normalizedProfitScore = 0;
        if (profitMap.containsKey(guy.getId())) {
          normalizedProfitScore = profitMap.get(guy.getId()) / profitMax;
        }

        double normalizedHubScore = holderToHubScore.get(guy) / hubMax;
        double suspicionScore = normalizedHubScore * 0.6 + normalizedProfitScore * 0.4;

        guy.setSuspicionScore(suspicionScore);
        orderedSuspicion.add(guy);
      }
    } catch (Exception e) {
      e.printStackTrace();
      System.out.println("ERROR: Could not connect to database querier");
    }
    int size = orderedSuspicion.size();
    for(int i = 0; i < size; i++){
      suspicionList.add(orderedSuspicion.poll());
    }
    return suspicionList;
  }
}