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;
}
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;
}
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;
}
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);
}
}
}
}
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;
}
Aggregations