Skip to content

Instantly share code, notes, and snippets.

@lambdaydoty
Created December 27, 2024 02:57
Show Gist options
  • Save lambdaydoty/949123d3ca81a204ed00916f5f90ae95 to your computer and use it in GitHub Desktop.
Save lambdaydoty/949123d3ca81a204ed00916f5f90ae95 to your computer and use it in GitHub Desktop.
A priority first search unifying the four classical search algorithms: DFS, BFS, Dijkstra's shortest path, Prim's minimum spanning tree
import java.util.*;
import java.util.function.*;
class PriorityFirstSearch {
private final int N = 100;
private int _tick = 0;
private void byPFS(char src) {
/**
* To emcompass all four kinds of search (dfs, bfs, dijkstra, prim),
* we leverage the linear ordering of Java Integer:
* Integer.MIN_VALUE, ..., 0, 1, 2, ..., Integer.MAX_VALUE
* and denote by:
*
* 1. priority[u] == Integer.MIN_VALUE ≡ u is a processed/tree/BLACK vertex.
*
* 2. priority[u] == Integer.MAX_VALUE ≡ u is a unseen/unvisited/WHITE vertex.
*
* 3. otherwise ≡ u is a visited-but-not-processed/queued/fringe/GREY vertex.
*
*
* ________________
* @BLACK.... |_*GREY____|..___ 0WHITE...
* ^^^^^^^^^^^^^^^^
* the priority queue
*
* ---@---@---*---0
* |\_ | |
* | \| |
* *---*---0
* | | |
* | | |
* 0---0---0
*/
final int[] priority = new int[N];
final int V = 0; // vertex
final int P = 1; // priority
final PriorityQueue<int[]> q = new PriorityQueue<>((vec1, vec2) -> {
return vec1[P] != vec2[P]
? Integer.compare(vec1[P], vec2[P])
: Integer.compare(vec1[V], vec2[V]); // Post an ordering in case of a tie (dfs or bfs)
});
Arrays.fill(priority, Integer.MAX_VALUE);
priority[src] = 0;
q.add(new int[]{ src, priority[src] });
while (!q.isEmpty()) {
/*
* Each time we process a fringe of from u to v:
* u: current vertex or tree vertex
* v: next vertex or fringe vertex
*/
int[] curr = q.remove();
char u = curr[V];
int u_p = curr[P];
if (u_p != priority[u]) continue;
/* Visit u */System.out.format("Visit vertex %d on tick %d\n ", u, ++_tick);
for (char v : adj.get(u)) {
/* Compute the priority */
int p = -tick; // dfs
// int p = +tick; // bfs
// int p = u_p + dist(u,v); // dijkstra
// int p = dist(u,v); // prim
if (priority[v] > p) {
// if (priority[v] == Integer.MAX_VALUE) {
// System.out.format("(unseen: %d)\n", v);
// } else {
// System.out.format("(FRINGE: %d)\n", v);
// }
priority[v] = p;
q.add(new int[]{ v, priority[v] });
} else {
// if (priority[v] == Integer.MIN_VALUE) {
// System.out.format("(tree: %d)\n", v);
// } else {
// System.out.format("(fringe: %d)\n", v);
// }
}
}
priority[u] = Integer.MIN_VALUE; // Blacken u
}
}
private int dist(int u, int v) {
// ...
return Integer.MIN_VALUE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment