Search in sources :

Example 1 with UnionFind

use of chapter1.section5.UnionFind in project algorithms-sedgewick-wayne by reneargento.

the class Exercise43_RandomEuclideanGraphs method main.

// Parameters example: 6 0.5 100
public static void main(String[] args) {
    int vertices = Integer.parseInt(args[0]);
    double radius = Double.parseDouble(args[1]);
    int numberOfGraphs = Integer.parseInt(args[2]);
    List<Exercise37_EuclideanGraphs.EuclideanGraph> randomEuclideanGraphs = new Exercise43_RandomEuclideanGraphs().generateRandomEuclideanGraphs(numberOfGraphs, vertices, radius);
    Exercise37_EuclideanGraphs.EuclideanGraph firstEuclideanGraph = randomEuclideanGraphs.get(0);
    firstEuclideanGraph.show(-0.1, 1.1, -0.1, 1.1, 0.03);
    UnionFind unionFind = new UnionFind(vertices);
    for (int vertex = 0; vertex < vertices; vertex++) {
        for (int neighbor : firstEuclideanGraph.adjacent(vertex)) {
            unionFind.union(vertex, neighbor);
        }
    }
    // Check theory that if "radius" is larger than threshold value SQRT(ln(V) / (Math.PI * V)) then the graph is
    // almost certainly connected. Otherwise, it is almost certainly disconnected.
    double thresholdValue = Math.sqrt(Math.log(vertices) / (Math.PI * vertices));
    StdOut.println("Expected to be connected: " + (radius > thresholdValue));
    StdOut.println("Is connected: " + (unionFind.count() == 1));
}
Also used : UnionFind(chapter1.section5.UnionFind)

Example 2 with UnionFind

use of chapter1.section5.UnionFind 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;
}
Also used : PriorityQueueResize(chapter2.section4.PriorityQueueResize) ArrayList(java.util.ArrayList) UnionFind(chapter1.section5.UnionFind) SeparateChainingHashTable(chapter3.section4.SeparateChainingHashTable) Queue(chapter1.section3.Queue) HashSet(chapter3.section5.HashSet)

Example 3 with UnionFind

use of chapter1.section5.UnionFind in project algorithms-sedgewick-wayne by reneargento.

the class Exercise33_Certification method check.

// The order of growth of the running time of this method is O(V * E)
public boolean check(EdgeWeightedGraph edgeWeightedGraph, Queue<Edge> proposedMinimumSpanningTree) {
    // 1- Check if it is a spanning tree
    UnionFind unionFind = new UnionFind(edgeWeightedGraph.vertices());
    // O(V)
    for (Edge edge : proposedMinimumSpanningTree) {
        int vertex1 = edge.either();
        int vertex2 = edge.other(vertex1);
        if (unionFind.connected(vertex1, vertex2)) {
            // Cycle found
            return false;
        }
        unionFind.union(vertex1, vertex2);
    }
    // O(1)
    if (unionFind.count() != 1) {
        return false;
    }
    // O(V * E)
    for (Edge edgeInMST : proposedMinimumSpanningTree) {
        unionFind = new UnionFind(edgeWeightedGraph.vertices());
        // Add all edges in the MST except edgeInMST
        for (Edge edge : proposedMinimumSpanningTree) {
            if (edge != edgeInMST) {
                int vertex1 = edge.either();
                int vertex2 = edge.other(vertex1);
                unionFind.union(vertex1, vertex2);
            }
        }
        // Check that edgeInMST is the minimum-weight edge in the crossing cut
        for (Edge edge : edgeWeightedGraph.edges()) {
            int vertex1 = edge.either();
            int vertex2 = edge.other(vertex1);
            if (!unionFind.connected(vertex1, vertex2)) {
                if (edge.weight() < edgeInMST.weight()) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : UnionFind(chapter1.section5.UnionFind)

Example 4 with UnionFind

use of chapter1.section5.UnionFind in project algorithms-sedgewick-wayne by reneargento.

the class Exercise35_RandomEuclideanEdgeWeightedGraphs method main.

// Parameters example: 6 0.5 100
public static void main(String[] args) {
    int vertices = Integer.parseInt(args[0]);
    double radius = Double.parseDouble(args[1]);
    int numberOfGraphs = Integer.parseInt(args[2]);
    List<Exercise30_EuclideanWeightedGraphs.EuclideanEdgeWeightedGraph> randomEuclideanGraphs = new Exercise35_RandomEuclideanEdgeWeightedGraphs().generateRandomEuclideanEdgeWeightedGraphs(numberOfGraphs, vertices, radius);
    Exercise30_EuclideanWeightedGraphs.EuclideanEdgeWeightedGraph firstEuclideanEdgeWeightedGraph = randomEuclideanGraphs.get(0);
    firstEuclideanEdgeWeightedGraph.show(-0.1, 1.1, -0.1, 1.1, 0.03);
    UnionFind unionFind = new UnionFind(vertices);
    for (int vertex = 0; vertex < vertices; vertex++) {
        for (Edge edge : firstEuclideanEdgeWeightedGraph.adjacent(vertex)) {
            int neighbor = edge.other(vertex);
            unionFind.union(vertex, neighbor);
        }
    }
    // Check theory that if "radius" is larger than threshold value SQRT(ln(V) / (Math.PI * V)) then the graph is
    // almost certainly connected. Otherwise, it is almost certainly disconnected.
    double thresholdValue = Math.sqrt(Math.log(vertices) / (Math.PI * vertices));
    StdOut.println("Expected to be connected: " + (radius > thresholdValue));
    StdOut.println("Is connected: " + (unionFind.count() == 1));
}
Also used : UnionFind(chapter1.section5.UnionFind)

Example 5 with UnionFind

use of chapter1.section5.UnionFind in project algorithms-sedgewick-wayne by reneargento.

the class Exercise50_RandomEuclideanEdgeWeightedDigraphs method main.

// Parameters example: 6 0.5 100
public static void main(String[] args) {
    int vertices = Integer.parseInt(args[0]);
    double radius = Double.parseDouble(args[1]);
    int numberOfDigraphs = Integer.parseInt(args[2]);
    List<EdgeWeightedDigraphInterface> randomEuclideanEdgeWeightedDigraphs = new Exercise50_RandomEuclideanEdgeWeightedDigraphs().generateRandomEuclideanEdgeWeightedDigraphs(numberOfDigraphs, vertices, radius);
    EdgeWeightedDigraphInterface firstEuclideanEdgeWeightedDigraph = randomEuclideanEdgeWeightedDigraphs.get(0);
    // Not used in EdgeWeightedDigraphInterface
    // firstEuclideanEdgeWeightedDigraph.show(-0.1, 1.1, -0.1, 1.1, 0.03, 0.01, 0.03);
    UnionFind unionFind = new UnionFind(vertices);
    for (int vertex = 0; vertex < vertices; vertex++) {
        for (DirectedEdge edge : firstEuclideanEdgeWeightedDigraph.adjacent(vertex)) {
            int neighbor = edge.to();
            unionFind.union(vertex, neighbor);
        }
    }
    // Check theory that if "radius" is larger than threshold value SQRT(ln(V) / (Math.PI * V)) then the graph is
    // almost certainly connected. Otherwise, it is almost certainly disconnected.
    double thresholdValue = Math.sqrt(Math.log(vertices) / (Math.PI * vertices));
    StdOut.println("Expected to be connected (if it were an undirected graph): " + (radius > thresholdValue));
    StdOut.println("Would be connected (if it were an undirected graph): " + (unionFind.count() == 1));
    StdOut.println("\nRandom Euclidean edge-weighted digraph:\n");
    StdOut.println(firstEuclideanEdgeWeightedDigraph);
}
Also used : UnionFind(chapter1.section5.UnionFind)

Aggregations

UnionFind (chapter1.section5.UnionFind)8 ArrayList (java.util.ArrayList)3 Queue (chapter1.section3.Queue)1 PriorityQueueResize (chapter2.section4.PriorityQueueResize)1 SeparateChainingHashTable (chapter3.section4.SeparateChainingHashTable)1 HashSet (chapter3.section5.HashSet)1