Evaluate edge weight based on node and edge type (#486)

Summary:
PageRank wants an _edge evaluator_: a function mapping an edge to its
to-weight and fro-weight. This commit provides functions for creating
edge evaluators based on the high-level, coarse notions of node and edge
types. We use [the formulation described in a comment on #476][1].

Paired with @decentralion.

[1]: https://github.com/sourcecred/sourcecred/issues/476#issuecomment-402576435

Test Plan:
None. We will add tests later. We promise!

wchargin-branch: edge-weight-generators
This commit is contained in:
William Chargin 2018-07-04 18:24:34 -07:00 committed by GitHub
parent 88cd736dec
commit 1749676459
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 1 deletions

View File

@ -0,0 +1,56 @@
// @flow
import {
type Edge,
type EdgeAddressT,
type NodeAddressT,
EdgeAddress,
NodeAddress,
} from "../../core/graph";
import type {EdgeEvaluator} from "../../core/attribution/pagerank";
export function byEdgeType(
prefixes: $ReadOnlyArray<{|
+prefix: EdgeAddressT,
+weight: number,
+directionality: number,
|}>
): EdgeEvaluator {
return function evaluator(edge: Edge) {
const datum = prefixes.find(({prefix}) =>
EdgeAddress.hasPrefix(edge.address, prefix)
);
if (datum == null) {
throw new Error(EdgeAddress.toString(edge.address));
}
const {weight, directionality} = datum;
return {
toWeight: directionality * weight,
froWeight: (1 - directionality) * weight,
};
};
}
export function byNodeType(
base: EdgeEvaluator,
prefixes: $ReadOnlyArray<{|
+prefix: NodeAddressT,
+weight: number,
|}>
): EdgeEvaluator {
return function evaluator(edge: Edge) {
const srcDatum = prefixes.find(({prefix}) =>
NodeAddress.hasPrefix(edge.src, prefix)
);
const dstDatum = prefixes.find(({prefix}) =>
NodeAddress.hasPrefix(edge.dst, prefix)
);
if (srcDatum == null || dstDatum == null) {
throw new Error(EdgeAddress.toString(edge.address));
}
const baseResult = base(edge);
return {
toWeight: dstDatum.weight * baseResult.toWeight,
froWeight: srcDatum.weight * baseResult.froWeight,
};
};
}

View File

@ -18,6 +18,9 @@ export type PagerankOptions = {|
+maxIterations?: number,
|};
export type {EdgeWeight} from "./graphToMarkovChain";
export type EdgeEvaluator = (Edge) => EdgeWeight;
function defaultOptions(): PagerankOptions {
return {
verbose: false,
@ -29,7 +32,7 @@ function defaultOptions(): PagerankOptions {
export function pagerank(
graph: Graph,
edgeWeight: (Edge) => EdgeWeight,
edgeWeight: EdgeEvaluator,
options?: PagerankOptions
): PagerankResult {
const fullOptions = {