← Back to OneMasterChic Blog
Calculating
2) Subclass
Calculating distanceFromRoot with JGraphT’s BreadthFirstIterator
When you perform a root-by-root BFS, you can capture each vertex’s depth (distance from that root) on the fly. Below are two patterns: one that injects depth-tracking into your existing loop, and another that subclasses BreadthFirstIterator for cleaner reuse.
1) On-the-fly distances in your existing loop
Seed a per-root map with the root at depth 0, then for each traversed edge compute child depth = parent depth + 1. At the end you’ll have:
allDistances→ Map of root → (vertex → depth)visitFrequency→ global counts
public void processGraphByBreadthFirst( Map,Priority> priorityMap) {
Map<Class<? extends BaseEntity>, Map<Class<? extends BaseEntity>,Integer>> allDistances = new HashMap<>(); Map<Class<? extends BaseEntity>,Integer> visitFrequency = new HashMap<>();
brainzGraphModel.getEntityDirectedGraph() .vertexSet() .forEach(root -> {
Map<Class<? extends BaseEntity>,Integer> distances = new HashMap<>(); distances.put(root, 0); Set<PriorityEdge> visitedEdges = new HashSet<>();
BreadthFirstIterator<Class<? extends BaseEntity>,PriorityEdge> bfs = brainzGraphModel.getBreadthFirstIterator(root);
while (bfs.hasNext()) { Class<? extends BaseEntity> next = bfs.next(); Class<? extends BaseEntity> parent = bfs.getParent(next);
if (parent != null) { int parentDepth = distances.getOrDefault(parent, 0); int depthFromRoot = parentDepth + 1; distances.put(next, depthFromRoot);
PriorityEdge edge = brainzGraphModel .getEntityDirectedGraph() .getEdge(parent, next); if (visitedEdges.add(edge)) { visitFrequency.merge(next, 1, Integer::sum); }
// … your priority/weight logic here … } }
allDistances.put(root, distances); });
// allDistances.get(root).get(vertex) gives distanceFromRoot }
2) Subclass BreadthFirstIterator to track depth
If you reuse BFS+depth often, a dedicated subclass encapsulates the logic:
public class BFSWithDepth<V,E> extends BreadthFirstIterator<V,E> { private final Map<V,Integer> depth = new HashMap<>();
public BFSWithDepth(Graph<V,E> g, V start) { super(g, start); depth.put(start, 0); }
@Override protected void encounterVertex(V v, E viaEdge) { super.encounterVertex(v, viaEdge); V parent = Graphs.getOppositeVertex(getGraph(), viaEdge, v); depth.put(v, depth.get(parent) + 1); }
public int depthOf(V v) { return depth.getOrDefault(v, -1); } }
Usage:
BFSWithDepth<Class<? extends BaseEntity>,PriorityEdge> bfs = new BFSWithDepth<>(graph, root); while (bfs.hasNext()) { Class<? extends BaseEntity> v = bfs.next(); int dist = bfs.depthOf(v); // … process with dist … }
Either approach gives you a reliable distanceFromRoot to feed into your scoring adjustments (depth penalty, novelty boost, etc.).
Comments
Post a Comment