Search in sources :

Example 1 with HashSet

use of chapter3.section5.HashSet in project algorithms-sedgewick-wayne by reneargento.

the class Exercise37_RealEdgeWeightedGraphs method randomRealEdgeWeightedGraph.

private EdgeWeightedGraph randomRealEdgeWeightedGraph(int randomVerticesToChoose, int randomEdgesToChoose) {
    String filePath = Constants.FILES_PATH + Constants.US_AIR_FILE;
    String separator = " ";
    In in = new In(filePath);
    String[] firstLine = in.readLine().split(separator);
    int vertices = Integer.parseInt(firstLine[0]);
    int edges = Integer.parseInt(firstLine[2]);
    EdgeWeightedGraph fullGraph = new EdgeWeightedGraph();
    for (int edge = 0; edge < edges; edge++) {
        String[] connection = in.readLine().split(separator);
        int city1 = Integer.parseInt(connection[0]);
        int city2 = Integer.parseInt(connection[1]);
        double distance = Double.parseDouble(connection[2]);
        Edge newEdge = new Edge(city1, city2, distance);
        fullGraph.addEdge(newEdge);
    }
    EdgeWeightedGraph randomSubGraph = new EdgeWeightedGraph();
    SeparateChainingHashTable<Integer, Integer> graphToSubGraphMap = new SeparateChainingHashTable<>();
    List<Edge> allSubGraphEdges = new ArrayList<>();
    HashSet<Integer> chosenVertices = new HashSet<>();
    for (int vertex = 0; vertex < randomVerticesToChoose; vertex++) {
        // Randomly choose a vertex between 1 and vertices
        int randomVertexId = StdRandom.uniform(vertices) + 1;
        if (chosenVertices.contains(randomVertexId)) {
            continue;
        }
        chosenVertices.add(randomVertexId);
        int subGraphVertexId1 = graphToSubGraphMap.size();
        graphToSubGraphMap.put(randomVertexId, subGraphVertexId1);
        randomSubGraph.addVertex(subGraphVertexId1);
        for (Edge edge : fullGraph.adjacent(randomVertexId)) {
            int vertexId2 = edge.other(randomVertexId);
            int subGraphVertexId2;
            if (!graphToSubGraphMap.contains(vertexId2)) {
                subGraphVertexId2 = graphToSubGraphMap.size();
                graphToSubGraphMap.put(vertexId2, subGraphVertexId2);
                randomSubGraph.addVertex(subGraphVertexId2);
            } else {
                subGraphVertexId2 = graphToSubGraphMap.get(vertexId2);
            }
            allSubGraphEdges.add(new Edge(subGraphVertexId1, subGraphVertexId2, edge.weight()));
        }
    }
    // Randomly choose E edges from the subgraph induced by the random vertices
    if (randomEdgesToChoose > allSubGraphEdges.size()) {
        throw new IllegalArgumentException("Not enough edges to choose from the induced subgraph");
    }
    Edge[] allSubGraphEdgesArray = new Edge[allSubGraphEdges.size()];
    int allSubGraphEdgesArrayIndex = 0;
    HashSet<Integer> edgesChosen = new HashSet<>();
    for (Edge edge : allSubGraphEdges) {
        allSubGraphEdgesArray[allSubGraphEdgesArrayIndex++] = edge;
    }
    for (int edge = 0; edge < randomEdgesToChoose; edge++) {
        // Randomly choose an edge
        int randomEdgeId = StdRandom.uniform(allSubGraphEdgesArray.length);
        if (edgesChosen.contains(randomEdgeId)) {
            continue;
        }
        edgesChosen.add(randomEdgeId);
        Edge randomEdge = allSubGraphEdgesArray[randomEdgeId];
        int subGraphVertexId1 = randomEdge.either();
        int subGraphVertexId2 = randomEdge.other(subGraphVertexId1);
        Edge newEdge = new Edge(subGraphVertexId1, subGraphVertexId2, randomEdge.weight());
        randomSubGraph.addEdge(newEdge);
    }
    return randomSubGraph;
}
Also used : In(edu.princeton.cs.algs4.In) ArrayList(java.util.ArrayList) SeparateChainingHashTable(chapter3.section4.SeparateChainingHashTable) HashSet(chapter3.section5.HashSet)

Example 2 with HashSet

use of chapter3.section5.HashSet in project algorithms-sedgewick-wayne by reneargento.

the class Exercise45_RealWorldGraphs method randomRealGraph.

private Graph randomRealGraph(int randomVerticesToChoose, int randomEdgesToChoose) {
    String filePath = Constants.FILES_PATH + Constants.US_AIR_FILE;
    String separator = " ";
    In in = new In(filePath);
    String[] firstLine = in.readLine().split(separator);
    int vertices = Integer.parseInt(firstLine[0]);
    int edges = Integer.parseInt(firstLine[2]);
    Graph fullGraph = new Graph();
    for (int edge = 0; edge < edges; edge++) {
        String[] connection = in.readLine().split(separator);
        int city1 = Integer.parseInt(connection[0]);
        int city2 = Integer.parseInt(connection[1]);
        // Not used in this exercise
        double distance = Double.parseDouble(connection[2]);
        fullGraph.addEdge(city1, city2);
    }
    Graph randomSubGraph = new Graph();
    SeparateChainingHashTable<Integer, Integer> graphToSubGraphMap = new SeparateChainingHashTable<>();
    List<Edge> allSubGraphEdges = new ArrayList<>();
    HashSet<Integer> chosenVertices = new HashSet<>();
    for (int vertex = 0; vertex < randomVerticesToChoose; vertex++) {
        // Randomly choose a vertex between 1 and vertices
        int randomVertexId = StdRandom.uniform(vertices) + 1;
        if (chosenVertices.contains(randomVertexId)) {
            continue;
        }
        chosenVertices.add(randomVertexId);
        int subGraphVertexId1 = graphToSubGraphMap.size();
        graphToSubGraphMap.put(randomVertexId, subGraphVertexId1);
        randomSubGraph.addVertex(subGraphVertexId1);
        for (Integer neighbor : fullGraph.adjacent(randomVertexId)) {
            int subGraphVertexId2;
            if (!graphToSubGraphMap.contains(neighbor)) {
                subGraphVertexId2 = graphToSubGraphMap.size();
                graphToSubGraphMap.put(neighbor, subGraphVertexId2);
                randomSubGraph.addVertex(subGraphVertexId2);
            } else {
                subGraphVertexId2 = graphToSubGraphMap.get(neighbor);
            }
            allSubGraphEdges.add(new Edge(subGraphVertexId1, subGraphVertexId2));
        }
    }
    // Randomly choose E edges from the subgraph induced by the random vertices
    if (randomEdgesToChoose > allSubGraphEdges.size()) {
        throw new IllegalArgumentException("Not enough edges to choose from the induced subgraph");
    }
    Edge[] allSubGraphEdgesArray = new Edge[allSubGraphEdges.size()];
    int allSubGraphEdgesArrayIndex = 0;
    HashSet<Integer> edgesChosen = new HashSet<>();
    for (Edge edge : allSubGraphEdges) {
        allSubGraphEdgesArray[allSubGraphEdgesArrayIndex++] = edge;
    }
    for (int edge = 0; edge < randomEdgesToChoose; edge++) {
        // Randomly choose an edge
        int randomEdgeId = StdRandom.uniform(allSubGraphEdgesArray.length);
        if (edgesChosen.contains(randomEdgeId)) {
            continue;
        }
        edgesChosen.add(randomEdgeId);
        Edge randomEdge = allSubGraphEdgesArray[randomEdgeId];
        randomSubGraph.addEdge(randomEdge.vertex1, randomEdge.vertex2);
    }
    return randomSubGraph;
}
Also used : In(edu.princeton.cs.algs4.In) ArrayList(java.util.ArrayList) SeparateChainingHashTable(chapter3.section4.SeparateChainingHashTable) HashSet(chapter3.section5.HashSet)

Example 3 with HashSet

use of chapter3.section5.HashSet 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 4 with HashSet

use of chapter3.section5.HashSet in project algorithms-sedgewick-wayne by reneargento.

the class Exercise44_WebCrawler method crawlWeb.

public void crawlWeb(String sourceWebPage) {
    // timeout connection after 500 milliseconds
    System.setProperty("sun.net.client.defaultConnectTimeout", "500");
    System.setProperty("sun.net.client.defaultReadTimeout", "1000");
    Queue<String> webPagesQueue = new Queue<>();
    webPagesQueue.enqueue(sourceWebPage);
    HashSet<String> visited = new HashSet<>();
    visited.add(sourceWebPage);
    while (!webPagesQueue.isEmpty()) {
        String currentWebPage = webPagesQueue.dequeue();
        String webPageContent;
        try {
            In in = new In(currentWebPage);
            webPageContent = in.readAll();
        } catch (IllegalArgumentException exception) {
            StdOut.println("Could not open " + currentWebPage);
            continue;
        }
        StdOut.println(currentWebPage + " crawled");
        /**
         ***********************************************************
         *  Find links of the form: http://xxx.yyy.zzz or https://xxx.yyy.zzz
         *  s? for either http or https
         *  \\w+ for one or more alpha-numeric characters
         *  \\. for dot
         ************************************************************
         */
        String regexp = "http(s?)://(\\w+\\.)+(\\w+)";
        Pattern pattern = Pattern.compile(regexp);
        Matcher matcher = pattern.matcher(webPageContent);
        // Find all matches
        while (matcher.find()) {
            String webPage = matcher.group();
            if (!visited.contains(webPage)) {
                webPagesQueue.enqueue(webPage);
                visited.add(webPage);
            }
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) In(edu.princeton.cs.algs4.In) Matcher(java.util.regex.Matcher) Queue(chapter1.section3.Queue) HashSet(chapter3.section5.HashSet)

Example 5 with HashSet

use of chapter3.section5.HashSet in project algorithms-sedgewick-wayne by reneargento.

the class Exercise50_RealWorldDigraphs method randomRealDigraph.

private Digraph randomRealDigraph(int randomVerticesToChoose, int randomEdgesToChoose) {
    String filePath = Constants.FILES_PATH + Constants.WEB_DIGRAPH_FILE;
    String separator = " ";
    In in = new In(filePath);
    // Not used
    String firstLine = in.readLine();
    String[] secondLine = in.readLine().split(separator);
    // Based on the digraph description
    int vertices = 875714;
    int edges = Integer.parseInt(secondLine[1]);
    Digraph fullDigraph = new Digraph();
    for (int edge = 0; edge < edges; edge++) {
        String[] connection = in.readLine().split(separator);
        int website1 = Integer.parseInt(connection[0]);
        int website2 = Integer.parseInt(connection[1]);
        fullDigraph.addEdge(website1, website2);
    }
    Digraph randomSubDigraph = new Digraph();
    SeparateChainingHashTable<Integer, Integer> digraphToSubDigraphMap = new SeparateChainingHashTable<>();
    List<DirectedEdge> allSubDigraphEdges = new ArrayList<>();
    HashSet<Integer> chosenVertices = new HashSet<>();
    for (int vertex = 0; vertex < randomVerticesToChoose; vertex++) {
        // Randomly choose a vertex between 1 and vertices
        int randomVertexId = StdRandom.uniform(vertices) + 1;
        if (chosenVertices.contains(randomVertexId)) {
            continue;
        }
        chosenVertices.add(randomVertexId);
        int subDigraphVertexId1 = digraphToSubDigraphMap.size();
        digraphToSubDigraphMap.put(randomVertexId, subDigraphVertexId1);
        randomSubDigraph.addVertex(subDigraphVertexId1);
        for (int neighbor : fullDigraph.adjacent(randomVertexId)) {
            int subDigraphVertexId2;
            if (!digraphToSubDigraphMap.contains(neighbor)) {
                subDigraphVertexId2 = digraphToSubDigraphMap.size();
                digraphToSubDigraphMap.put(neighbor, subDigraphVertexId2);
                randomSubDigraph.addVertex(subDigraphVertexId2);
            } else {
                subDigraphVertexId2 = digraphToSubDigraphMap.get(neighbor);
            }
            allSubDigraphEdges.add(new DirectedEdge(subDigraphVertexId1, subDigraphVertexId2));
        }
    }
    // Randomly choose E directed edges from the subdigraph induced by the random vertices
    if (randomEdgesToChoose > allSubDigraphEdges.size()) {
        throw new IllegalArgumentException("Not enough edges to choose from the induced subgraph");
    }
    DirectedEdge[] allSubDigraphEdgesArray = new DirectedEdge[allSubDigraphEdges.size()];
    int allSubDigraphEdgesArrayIndex = 0;
    HashSet<Integer> edgesChosen = new HashSet<>();
    for (DirectedEdge directedEdge : allSubDigraphEdges) {
        allSubDigraphEdgesArray[allSubDigraphEdgesArrayIndex++] = directedEdge;
    }
    for (int edge = 0; edge < randomEdgesToChoose; edge++) {
        // Randomly choose an edge
        int randomEdgeId = StdRandom.uniform(allSubDigraphEdgesArray.length);
        if (edgesChosen.contains(randomEdgeId)) {
            continue;
        }
        edgesChosen.add(randomEdgeId);
        DirectedEdge randomEdge = allSubDigraphEdgesArray[randomEdgeId];
        randomSubDigraph.addEdge(randomEdge.fromVertex, randomEdge.toVertex);
    }
    return randomSubDigraph;
}
Also used : In(edu.princeton.cs.algs4.In) ArrayList(java.util.ArrayList) SeparateChainingHashTable(chapter3.section4.SeparateChainingHashTable) HashSet(chapter3.section5.HashSet)

Aggregations

HashSet (chapter3.section5.HashSet)6 SeparateChainingHashTable (chapter3.section4.SeparateChainingHashTable)5 In (edu.princeton.cs.algs4.In)5 ArrayList (java.util.ArrayList)5 Queue (chapter1.section3.Queue)2 UnionFind (chapter1.section5.UnionFind)1 PriorityQueueResize (chapter2.section4.PriorityQueueResize)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1