2024-02-22 17:01:35 +00:00
|
|
|
package nu.marginalia.ranking.domains;
|
2024-02-16 17:04:58 +00:00
|
|
|
|
|
|
|
import gnu.trove.list.TIntList;
|
|
|
|
import gnu.trove.list.array.TIntArrayList;
|
2024-02-22 17:01:35 +00:00
|
|
|
import nu.marginalia.ranking.domains.accumulator.RankingResultAccumulator;
|
|
|
|
import nu.marginalia.ranking.domains.data.GraphSource;
|
|
|
|
import nu.marginalia.ranking.domains.jgrapht.PersonalizedPageRank;
|
2024-02-16 17:04:58 +00:00
|
|
|
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<Integer> influenceSet;
|
|
|
|
private final Graph<Integer, ?> graph;
|
|
|
|
|
|
|
|
public PageRankDomainRanker(GraphSource source,
|
|
|
|
List<Integer> influenceSet)
|
|
|
|
{
|
|
|
|
this.influenceSet = influenceSet;
|
|
|
|
this.graph = source.getGraph();
|
|
|
|
}
|
|
|
|
|
2024-02-16 19:22:01 +00:00
|
|
|
public static PageRankDomainRanker forDomainNames(GraphSource source,
|
|
|
|
List<String> influenceSet)
|
|
|
|
{
|
|
|
|
return new PageRankDomainRanker(source, source.domainIds(influenceSet));
|
|
|
|
}
|
|
|
|
|
2024-02-16 17:04:58 +00:00
|
|
|
@Override
|
|
|
|
public <T> T calculate(int resultCount, Supplier<RankingResultAccumulator<T>> accumulatorP) {
|
|
|
|
VertexScoringAlgorithm<Integer, Double> 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<Integer, Double> 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|