package happy.research.utils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * * @author guoguibing * */ public class MoleTrust { /** * Implementing MoleTrust Local Trust Metric: based on Epinions data set * * @param trust_data * @param sourceUser * @param horizon * @return map {trusted neighbour - trust score} , if no trusted neighbour, then return empty map */ @SuppressWarnings("unchecked") public static Map<Integer, Double> runAlgorithm(Map<Integer, Map<Integer, Double>> trust_data, Integer sourceUser, int horizon) { // all the visited nodes List<Integer> nodes = new ArrayList<>(40163); // source user - edges[target users - trust value] Map<Integer, Map<Integer, Double>> edges = new HashMap<>(40163); /* Step 1: construct directed graphic and remove cyclic */ int dist = 0; List<Integer>[] users = new List[horizon + 1]; users[dist] = new ArrayList<>(); users[dist].add(sourceUser); nodes.add(sourceUser); // Denote su: source user; tu: target user while (dist < horizon) { dist++; users[dist] = new ArrayList<>(); for (Integer su : users[dist - 1]) { Map<Integer, Double> tns = trust_data.get(su); if (tns == null) continue; // no trusted neighbours for (Integer tn : tns.keySet()) { if (!nodes.contains(tn) && !users[dist].contains(tn) && !users[dist - 1].contains(tn)) { users[dist].add(tn); } } } for (Integer su : users[dist - 1]) { Map<Integer, Double> tns = trust_data.get(su); if (tns == null) continue; for (Integer tu : tns.keySet()) { if (!nodes.contains(tu) && users[dist].contains(tu)) { Map<Integer, Double> tuTrusts; if (edges.containsKey(su)) tuTrusts = edges.get(su); else tuTrusts = new HashMap<>(); double trustValue = tns.get(tu); tuTrusts.put(tu, trustValue); edges.put(su, tuTrusts); } } } } /* Step 2: Evaluate trust score */ dist = 0; double threashold = 0.5; // trusted neighbours - trust score map Map<Integer, Double> trustScores = new HashMap<>(); trustScores.put(sourceUser, 1.0); while (dist < horizon) { dist++; for (Integer tu : users[dist]) { double sum = 0.0; double weights = 0.0; for (Integer su : users[dist - 1]) { Map<Integer, Double> tuTrusts = edges.get(su); if (tuTrusts == null) continue; // no edges for user su if (tuTrusts.containsKey(tu)) { double trust_edge = tuTrusts.get(tu); if (trust_edge > threashold) { sum += trust_edge * trustScores.get(su); weights += trustScores.get(su); } } } double score = sum / weights; trustScores.put(tu, score); } } trustScores.remove(sourceUser); return trustScores; } /** * Implement MoleTrust on FilmTrust data set * * @param trust_data * @param sourceUser * @param horizon * @return map {trusted neighbour - trust score} , if no trusted neighbour, then return empty map */ @SuppressWarnings("unchecked") public static Map<String, Double> runAlgorithm(Map<String, Map<String, Double>> trust_data, String sourceUser, int horizon) { // all the visited nodes List<String> nodes = new ArrayList<>(1000); // source user - edges[target users - trust value] Map<String, Map<String, Double>> edges = new HashMap<>(1000); /* Step 1: construct directed graphic and remove cyclic */ int dist = 0; List<String>[] users = new List[horizon + 1]; users[dist] = new ArrayList<>(); users[dist].add(sourceUser); nodes.add(sourceUser); // Denote su: source user; tu: target user while (dist < horizon) { dist++; users[dist] = new ArrayList<>(); for (String su : users[dist - 1]) { Map<String, Double> tns = trust_data.get(su); if (tns == null) continue; // no trusted neighbours for (String tn : tns.keySet()) { if (!nodes.contains(tn) && !users[dist].contains(tn) && !users[dist - 1].contains(tn)) { users[dist].add(tn); } } } for (String su : users[dist - 1]) { Map<String, Double> tns = trust_data.get(su); if (tns == null) continue; for (String tu : tns.keySet()) { if (!nodes.contains(tu) && users[dist].contains(tu)) { Map<String, Double> tuTrusts; if (edges.containsKey(su)) tuTrusts = edges.get(su); else tuTrusts = new HashMap<>(); double trustValue = trust_data.get(su).get(tu); tuTrusts.put(tu, trustValue); edges.put(su, tuTrusts); } } } } /* Step 2: Evaluate trust score */ dist = 0; double threashold = 0.0; // trusted neighbours - trust score map Map<String, Double> trustScores = new HashMap<>(); trustScores.put(sourceUser, 1.0); while (dist < horizon) { dist++; for (String tu : users[dist]) { double sum = 0.0; double weights = 0.0; for (String su : users[dist - 1]) { Map<String, Double> tuTrusts = edges.get(su); if (tuTrusts == null) continue; // no edges for user su if (tuTrusts.containsKey(tu)) { double trust_edge = tuTrusts.get(tu); if (trust_edge > threashold) { sum += trust_edge * trustScores.get(su); weights += trustScores.get(su); } } } double score = sum / weights; trustScores.put(tu, score); } } trustScores.remove(sourceUser); return trustScores; } }