/* * File: InfluencePotentialHandler.java * Authors: Tu-Thach Quach and Jeremy D. Wendt * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright 2016, Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the U.S. Government. * Export of this program may require a license from the United States * Government. See CopyrightHistory.txt for complete details. * */ package examples; import gov.sandia.cognition.annotation.PublicationReference; import gov.sandia.cognition.annotation.PublicationType; import gov.sandia.cognition.graph.DirectedNodeEdgeGraph; import gov.sandia.cognition.graph.DirectedWeightedNodeEdgeGraph; import gov.sandia.cognition.graph.inference.GraphWrappingEnergyFunction.PotentialHandler; import gov.sandia.cognition.collection.DoubleArrayList; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Potential handler for influence propagation. This class stores/returns what * each node's unary potential is and the per-edge pairwise potentials. * * @author jdwendt and tong * */ @PublicationReference(author = "Tu-Thach Quach and Jeremy D. Wendt", title = "A diffusion model for maximizing influence spread in large networks", type = PublicationType.Conference, publication = "Proceedings of the International Conference on Social Informatics", year = 2016) public class InfluencePotentialHandler implements PotentialHandler<Integer, String> { public static double MINIMUM_EDGE_POTENTIAL = 0.001; private final List<Integer> labels; private final DoubleArrayList unaryPotentials; /** * Creates a potential handler. * * @param graph The graph being wrapped * @param unaryPotentials Map of node (user) to unary potential of being in * state 1 (activated). */ public InfluencePotentialHandler(DirectedNodeEdgeGraph<String> graph, Map<String, Double> unaryPotentials) { labels = new ArrayList<>(); labels.add(0); labels.add(1); int n = graph.getNumNodes(); this.unaryPotentials = new DoubleArrayList(n); for (int i = 0; i < n; ++i) { this.unaryPotentials.add(-Double.MAX_VALUE); } for (Map.Entry<String, Double> e : unaryPotentials.entrySet()) { this.unaryPotentials.set(graph.getNodeId(e.getKey()), e.getValue()); } // Now make sure all were set for (int i = 0; i < n; ++i) { if (this.unaryPotentials.get(i) == -Double.MAX_VALUE) { throw new RuntimeException( "No unary potential passed in for node " + graph.getNode(i)); } } } /** * @see * PotentialHandler#getPossibleLabels(gov.sandia.cognition.graph.DirectedNodeEdgeGraph, * int) */ @Override public List<Integer> getPossibleLabels(DirectedNodeEdgeGraph<String> graph, int node) { return labels; } /** * @see * PotentialHandler#getPairwisePotential(gov.sandia.cognition.graph.DirectedNodeEdgeGraph, * int, java.lang.Object, java.lang.Object) */ @Override public double getPairwisePotential(DirectedNodeEdgeGraph<String> graph, int edgeId, Integer ilabel, Integer jlabel) { // 0.5 0.5 // 1-p p if (ilabel == 0) { return 0.5; // No influence. } else { double p = Math.max(MINIMUM_EDGE_POTENTIAL, ((DirectedWeightedNodeEdgeGraph<String>) graph).getEdgeWeight( edgeId)); if (jlabel == 0) { return 1 - p; } else { return p; } } } /** * @see * PotentialHandler#getUnaryPotential(gov.sandia.cognition.graph.DirectedNodeEdgeGraph, * int, java.lang.Object, java.lang.Object) */ @Override public double getUnaryPotential(DirectedNodeEdgeGraph<String> graph, int i, Integer label, Integer assignedLabel) { // A seed node will have an assigned label. if (assignedLabel != null) { if (label.equals(assignedLabel)) { return 1; } else { return 0; // Seed node cannot take on label 0. } } else { double p = unaryPotentials.get(i); if (label == 0) { return 1 - p; } else { return p; } } } }