use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.
the class FhEdgeWeights8_PLU8 method process.
@Override
public void process(Planar<GrayU8> input, FastQueue<Edge> edges) {
edges.reset();
int w = input.width - 1;
int h = input.height - 1;
// First consider the inner pixels
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride + 1;
int indexDst = +y * input.width + 1;
for (int x = 1; x < w; x++, indexSrc++, indexDst++) {
int weight1 = 0, weight2 = 0, weight3 = 0, weight4 = 0;
for (int i = 0; i < numBands; i++) {
GrayU8 band = input.getBand(i);
// (x,y)
int color0 = band.data[indexSrc] & 0xFF;
// (x+1,y)
int color1 = band.data[indexSrc + 1] & 0xFF;
// (x,y+1)
int color2 = band.data[indexSrc + input.stride] & 0xFF;
int diff1 = color0 - color1;
int diff2 = color0 - color2;
weight1 += diff1 * diff1;
weight2 += diff2 * diff2;
// (x+1,y+1)
int color3 = band.data[indexSrc + 1 + input.stride] & 0xFF;
// (x-1,y+1)
int color4 = band.data[indexSrc - 1 + input.stride] & 0xFF;
int diff3 = color0 - color3;
int diff4 = color0 - color4;
weight3 += diff3 * diff3;
weight4 += diff4 * diff4;
}
Edge e1 = edges.grow();
Edge e2 = edges.grow();
e1.sortValue = (float) Math.sqrt(weight1);
e1.indexA = indexDst;
e1.indexB = indexDst + 1;
e2.sortValue = (float) Math.sqrt(weight2);
e2.indexA = indexDst;
e2.indexB = indexDst + input.width;
Edge e3 = edges.grow();
Edge e4 = edges.grow();
e3.sortValue = (float) Math.sqrt(weight3);
e3.indexA = indexDst;
e3.indexB = indexDst + 1 + input.width;
e4.sortValue = (float) Math.sqrt(weight4);
e4.indexA = indexDst;
e4.indexB = indexDst - 1 + input.width;
}
}
// Handle border pixels
for (int y = 0; y < h; y++) {
checkAround(0, y, input, edges);
checkAround(w, y, input, edges);
}
for (int x = 0; x < w; x++) {
checkAround(x, h, input, edges);
}
}
use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.
the class FhEdgeWeights8_U8 method process.
@Override
public void process(GrayU8 input, FastQueue<Edge> edges) {
int w = input.width - 1;
int h = input.height - 1;
// First consider the inner pixels
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride + 1;
int indexDst = +y * input.width + 1;
for (int x = 1; x < w; x++, indexSrc++, indexDst++) {
// (x,y)
int color0 = input.data[indexSrc] & 0xFF;
// (x+1,y)
int color1 = input.data[indexSrc + 1] & 0xFF;
// (x,y+1)
int color2 = input.data[indexSrc + input.stride] & 0xFF;
Edge e1 = edges.grow();
Edge e2 = edges.grow();
e1.sortValue = Math.abs(color1 - color0);
e1.indexA = indexDst;
e1.indexB = indexDst + 1;
e2.sortValue = Math.abs(color2 - color0);
e2.indexA = indexDst;
e2.indexB = indexDst + input.width;
// (x+1,y+1)
int color3 = input.data[indexSrc + 1 + input.stride] & 0xFF;
// (x-1,y+1)
int color4 = input.data[indexSrc - 1 + input.stride] & 0xFF;
Edge e3 = edges.grow();
Edge e4 = edges.grow();
e3.sortValue = Math.abs(color3 - color0);
e3.indexA = indexDst;
e3.indexB = indexDst + 1 + input.width;
e4.sortValue = Math.abs(color4 - color0);
e4.indexA = indexDst;
e4.indexB = indexDst - 1 + input.width;
}
}
// Handle border pixels
for (int y = 0; y < h; y++) {
checkAround(0, y, input, edges);
checkAround(w, y, input, edges);
}
for (int x = 0; x < w; x++) {
checkAround(x, h, input, edges);
}
}
use of chapter4.section3.Edge in project BoofCV by lessthanoptimal.
the class FhEdgeWeights8_U8 method check.
private void check(int x, int y, int color0, int indexA, GrayU8 input, FastQueue<Edge> edges) {
if (!input.isInBounds(x, y))
return;
int indexSrc = input.startIndex + y * input.stride + x;
int indexB = +y * input.width + x;
int colorN = input.data[indexSrc] & 0xFF;
Edge e1 = edges.grow();
e1.sortValue = (float) Math.abs(color0 - colorN);
e1.indexA = indexA;
e1.indexB = indexB;
}
use of chapter4.section3.Edge in project algorithms-sedgewick-wayne by reneargento.
the class Exercise26_CriticalEdges method findCriticalEdges.
/**
* An edge e is critical if and only if it is a bridge in the subgraph containing all edges with weights
* less than or equal to the weight of edge e.
*
* Proof:
* 1st part: If an edge e is critical then it is a bridge in the subgraph containing all edges with weights
* less than or equal to the weight of edge e.
* Consider by contradiction that edge e is not a bridge in such subgraph. If it is not a bridge, then there is another
* edge f that connects the same components as e in the subgraph and it has weight less than or equal to e.
* In this case, edge e could be replaced by edge f in an MST and the MST weight would not increase.
* However, since e is critical and cannot be replaced by an edge with weight less than or equal to it,
* it must be a bridge in the subgraph.
*
* 2nd part: If an edge e is a bridge in the subgraph containing all edges with weights less than or equal to its
* weight then e is critical.
* Consider by contradiction that e is not critical. If e is not critical, then there must be another edge that
* could replace it in an MST and would not cause the MST weight to increase.
* However, if this edge existed, it would be part of the subgraph containing all edges with weights
* less than or equal to the weight of edge e. It would also connect both components C1 and C2 that are connected
* by edge e. However, e is a bridge and its removal would split components C1 and C2. So no such edge exists.
* Therefore, edge e is critical.
*/
// O(E lg E)
public Queue<Edge> findCriticalEdges(EdgeWeightedGraph edgeWeightedGraph) {
Queue<Edge> criticalEdges = new Queue<>();
// Modified Kruskal's algorithm
Queue<Edge> minimumSpanningTree = new Queue<>();
PriorityQueueResize<Edge> priorityQueue = new PriorityQueueResize<>(PriorityQueueResize.Orientation.MIN);
for (Edge edge : edgeWeightedGraph.edges()) {
priorityQueue.insert(edge);
}
UnionFind unionFind = new UnionFind(edgeWeightedGraph.vertices());
// Subgraph with components
EdgeWeightedGraphWithDelete componentsSubGraph = new EdgeWeightedGraphWithDelete(unionFind.count());
while (!priorityQueue.isEmpty() && minimumSpanningTree.size() < edgeWeightedGraph.vertices() - 1) {
Edge edge = priorityQueue.deleteTop();
int vertex1 = edge.either();
int vertex2 = edge.other(vertex1);
// Ineligible edges are never critical edges
if (unionFind.connected(vertex1, vertex2)) {
continue;
}
// Get next equal-weight edge block
double currentWeight = edge.weight();
HashSet<Edge> equalWeightEdges = new HashSet<>();
equalWeightEdges.add(edge);
while (!priorityQueue.isEmpty() && priorityQueue.peek().weight() == currentWeight) {
equalWeightEdges.add(priorityQueue.deleteTop());
}
if (equalWeightEdges.size() == 1) {
// There is no cycle, so this is a critical edge
criticalEdges.enqueue(edge);
unionFind.union(vertex1, vertex2);
minimumSpanningTree.enqueue(edge);
continue;
}
List<Edge> edgesToAddToComponentsSubGraph = new ArrayList<>();
// Map to make the mapping between edges in the components subgraph and the original graph
int averageMapListSize = Math.max(2, equalWeightEdges.size() / 20);
SeparateChainingHashTable<Edge, Edge> subGraphToGraphEdgeMap = new SeparateChainingHashTable<>(equalWeightEdges.size(), averageMapListSize);
HashSet<Integer> verticesInSubGraph = new HashSet<>();
// Generate subgraph with the current components
for (Edge edgeInCurrentBlock : equalWeightEdges.keys()) {
vertex1 = edgeInCurrentBlock.either();
vertex2 = edgeInCurrentBlock.other(vertex1);
int component1 = unionFind.find(vertex1);
int component2 = unionFind.find(vertex2);
Edge subGraphEdge = new Edge(component1, component2, currentWeight);
edgesToAddToComponentsSubGraph.add(subGraphEdge);
subGraphToGraphEdgeMap.put(subGraphEdge, edgeInCurrentBlock);
verticesInSubGraph.add(component1);
verticesInSubGraph.add(component2);
}
for (Edge edgeToAddToComponentSubGraph : edgesToAddToComponentsSubGraph) {
componentsSubGraph.addEdge(edgeToAddToComponentSubGraph);
}
// Run DFS to check if there is a cycle. Any edges in the cycle are non-critical.
// Every edge in the original graph will be visited by a DFS at most once.
HashSet<Edge> nonCriticalEdges = new HashSet<>();
// Use a different constructor for EdgeWeightedCycle to avoid O(E * V) runtime
EdgeWeightedCycle edgeWeightedCycle = new EdgeWeightedCycle(componentsSubGraph, verticesInSubGraph);
if (edgeWeightedCycle.hasCycle()) {
for (Edge edgeInCycle : edgeWeightedCycle.cycle()) {
Edge edgeInGraph = subGraphToGraphEdgeMap.get(edgeInCycle);
nonCriticalEdges.add(edgeInGraph);
}
}
// Clear components subgraph edges
for (Edge edgeToAddToComponentSubGraph : edgesToAddToComponentsSubGraph) {
componentsSubGraph.deleteEdge(edgeToAddToComponentSubGraph);
}
// Add all edges that belong to an MST to the MST
for (Edge edgeInCurrentBlock : equalWeightEdges.keys()) {
if (!nonCriticalEdges.contains(edgeInCurrentBlock)) {
criticalEdges.enqueue(edgeInCurrentBlock);
}
vertex1 = edgeInCurrentBlock.either();
vertex2 = edgeInCurrentBlock.other(vertex1);
if (!unionFind.connected(vertex1, vertex2)) {
unionFind.union(vertex1, vertex2);
// Add edge to the minimum spanning tree
minimumSpanningTree.enqueue(edge);
}
}
}
return criticalEdges;
}
use of chapter4.section3.Edge in project algorithms-sedgewick-wayne by reneargento.
the class Exercise41_OddLengthDirectedCycle method hasOddLengthDirectedCycle.
// A digraph G has an odd-length directed cycle if and only if one (or more) of its strong components
// (when treated as an undirected graph) is nonbipartite
// Proof
// If the digraph G has an odd-length directed cycle, then this cycle will be entirely contained in one of the
// strong components. When the strong component is treated as an undirected graph, the odd-length directed cycle
// becomes an odd-length cycle.
// An undirected graph is bipartite if and only if it has no odd-length cycle.
// Suppose a strong component of G is nonbipartite (when treated as an undirected graph). This means that there is
// an odd-length cycle C in the strong component, ignoring direction.
// If C is a directed cycle, then we are done.
// Otherwise, if and edge v->w is pointing in the "wrong" direction, we can replace it with an odd-length path that
// is pointing in the opposite direction (which preserves the parity of the number of edges in the cycle).
// To see how, note that there exists a directed path P from w to v because v and w are in the same strong component.
// If P has odd length, then we replace edge v->w by P; if P has even length, then this path P combined with
// v->w is an odd-length cycle.
// O(V + E)
public boolean hasOddLengthDirectedCycle(Digraph digraph) {
KosarajuSharirSCC kosarajuSharirSCC = new KosarajuSharirSCC(digraph);
Set<Integer>[] strongComponents = (Set<Integer>[]) new HashSet[kosarajuSharirSCC.count()];
for (int scc = 0; scc < strongComponents.length; scc++) {
strongComponents[scc] = new HashSet<>();
}
for (int vertex = 0; vertex < digraph.vertices(); vertex++) {
int strongComponentId = kosarajuSharirSCC.id(vertex);
strongComponents[strongComponentId].add(vertex);
}
for (int scc = 0; scc < strongComponents.length; scc++) {
// Uses optimized graph to make the algorithm O(V + E) instead of O(V^2)
// (No need to initialize all adjacency lists for the subGraphs)
OptimizedGraph subGraph = new OptimizedGraph(digraph.vertices());
for (int vertex : strongComponents[scc]) {
for (int neighbor : digraph.adjacent(vertex)) {
if (strongComponents[scc].contains(neighbor)) {
subGraph.addEdge(vertex, neighbor);
}
}
}
TwoColor twoColor = new TwoColor(subGraph);
if (!twoColor.isBipartite()) {
return true;
}
}
return false;
}
Aggregations