package nu.marginalia.ranking.domains; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; import nu.marginalia.ranking.domains.accumulator.RankingResultAccumulator; import nu.marginalia.ranking.domains.data.GraphSource; import nu.marginalia.ranking.domains.jgrapht.PersonalizedPageRank; import org.jgrapht.Graph; import org.jgrapht.alg.interfaces.VertexScoringAlgorithm; import org.jgrapht.alg.scoring.PageRank; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class PageRankDomainRanker implements RankingAlgorithm { private final List influenceSet; private final Graph graph; public PageRankDomainRanker(GraphSource source, List influenceSet) { this.influenceSet = influenceSet; this.graph = source.getGraph(); } public static PageRankDomainRanker forDomainNames(GraphSource source, List influenceSet) { return new PageRankDomainRanker(source, source.domainIds(influenceSet)); } @Override public T calculate(int resultCount, Supplier> accumulatorP) { VertexScoringAlgorithm pageRank; if (influenceSet != null && !influenceSet.isEmpty()) { pageRank = new PersonalizedPageRank<>(graph, influenceSet); } else { pageRank = new PageRank<>(graph); } TIntList results = new TIntArrayList(resultCount); pageRank.getScores().entrySet() .stream() .sorted(Comparator.comparing((Map.Entry e) -> -e.getValue())) .limit(resultCount) .map(Map.Entry::getKey) .forEach(results::add); var accumulator = accumulatorP.get(); for (int i = 0; i < results.size(); i++) { accumulator.add(results.get(i), i); } return accumulator.get(); } }