Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In Java: // Exercise 4.1.16 package algs41; import stdlib.*; // This is problem

ID: 3920864 • Letter: I

Question

In Java:

// Exercise 4.1.16

package algs41;

import stdlib.*;

// This is problem 4.1.16 from the textbook

//

// You need only change the constructor.

// You can also change the main method.

// But you should not change eccentricity(), diameter(), radius(), center() or isCenter()

// You can (and should!) add more private methods (such as bfs or dfs)

//

// TODO: complete the following, using only Graph and GraphGenerator.

// You may copy code from other classes in algs41, but you should not use the classes themselves.

// In particular, you may not use BreadthFirstPaths although you may copy code from there.

//

// Definitions:

// - The "distance" from vertex v to vertex w is the length of the shortest path from v to w.

// - The "eccentricity" of a vertex v is distance to the farthest vertex from v.

// - The "diameter" of a graph is the maximum eccentricity of any vertex.

// - The "radius" of a graph is the smallest eccentricity of any vertex.

// - A "center" is a vertex whose eccentricity is the radius. The center is not necessarily unique.

public class MyGraphProperties {

   int[] eccentricity;

   int diameter;

   int radius;

   int center;

   // Constructor can be linear in G.V() * G.E()

   public MyGraphProperties(Graph G) {

       this.eccentricity = new int[G.V()];

       int diameter = Integer.MIN_VALUE;

       int radius = Integer.MAX_VALUE;

       int center = -1;

       // If G.V()==0, then these are the correct values.

       // If G is not connected, you should throw a new IllegalArgumentException()

       // I suggest that you first get it to work for a connected graph

       // This will require that you traverse the graph starting from some node (say 0)

       // You can then adjust your code so that it throws an exception in the case that all nodes are not visited

       // TODO

       // compute the eccentricity, diameter, radius and center

       // The center of the graph is not unique, set center to SOME center --- it does not matter which one

       this.diameter = diameter;

       this.radius = radius;

       this.center = center;

   }

   // Do not change the following constant time methods

   public int eccentricity(int v) { return eccentricity[v]; }

   public int diameter() { return diameter; }

   public int radius() { return radius; }

   public int center() { return center; }

   public boolean isCenter(int v) { return eccentricity[v] == radius; }

   public static void main(String[] args) {

       //Graph G = GraphGenerator.fromIn (new In("data/tinyG.txt")); // this is non-connected -- should throw an exception

       //Graph G = GraphGenerator.connected (10, 20, 2); // Random non-connected graph -- should throw an exception

       Graph G = GraphGenerator.fromIn (new In("data/tinyCG.txt")); // diameter=2, radius=2, every node is a center

       //Graph G = GraphGenerator.binaryTree (10); // A complete binary tree

       //Graph G = GraphGenerator.path (10); // A path -- diameter=V-1

       //Graph G = GraphGenerator.connected (20, 400); // Random connected graph

       StdOut.println(G);

       G.toGraphviz ("g.png");

       MyGraphProperties gp = new MyGraphProperties(G);

       for (int v = 0; v < G.V(); v++)

           StdOut.format ("eccentricity of %d: %d ", v, gp.eccentricity (v));

       StdOut.format ("diameter=%d, radius=%d, center=%d ", gp.diameter(), gp.radius (), gp.center ());

   }

}

Explanation / Answer

public class GraphGenerator {

private static final class Edge implements Comparable<Edge> {

private int v;

private int w;

private Edge(int v, int w) {

if (v < w) {

this.v = v;

this.w = w;

}

else {

this.v = w;

this.w = v;

}

}

public int compareTo(Edge that) {

if (this.v < that.v) return -1;

if (this.v > that.v) return +1;

if (this.w < that.w) return -1;

if (this.w > that.w) return +1;

return 0;

}

}

// this class cannot be instantiated

private GraphGenerator() { }

/**

* Returns a random simple graph containing {@code V} vertices and {@code E} edges.

* @param V the number of vertices

* @param E the number of vertices

* @return a random simple graph on {@code V} vertices, containing a total

* of {@code E} edges

* @throws IllegalArgumentException if no such simple graph exists

*/

public static Graph simple(int V, int E) {

if (E > (long) V*(V-1)/2) throw new IllegalArgumentException("Too many edges");

if (E < 0) throw new IllegalArgumentException("Too few edges");

Graph G = new Graph(V);

SET<Edge> set = new SET<Edge>();

while (G.E() < E) {

int v = StdRandom.uniform(V);

int w = StdRandom.uniform(V);

Edge e = new Edge(v, w);

if ((v != w) && !set.contains(e)) {

set.add(e);

G.addEdge(v, w);

}

}

return G;

}

/**

* Returns a random simple graph on {@code V} vertices, with an

* edge between any two vertices with probability {@code p}. This is sometimes

* referred to as the Erdos-Renyi random graph model.

* @param V the number of vertices

* @param p the probability of choosing an edge

* @return a random simple graph on {@code V} vertices, with an edge between

* any two vertices with probability {@code p}

* @throws IllegalArgumentException if probability is not between 0 and 1

*/

public static Graph simple(int V, double p) {

if (p < 0.0 || p > 1.0)

throw new IllegalArgumentException("Probability must be between 0 and 1");

Graph G = new Graph(V);

for (int v = 0; v < V; v++)

for (int w = v+1; w < V; w++)

if (StdRandom.bernoulli(p))

G.addEdge(v, w);

return G;

}

/**

* Returns the complete graph on {@code V} vertices.

* @param V the number of vertices

* @return the complete graph on {@code V} vertices

*/

public static Graph complete(int V) {

return simple(V, 1.0);

}

/**

* Returns a complete bipartite graph on {@code V1} and {@code V2} vertices.

* @param V1 the number of vertices in one partition

* @param V2 the number of vertices in the other partition

* @return a complete bipartite graph on {@code V1} and {@code V2} vertices

* @throws IllegalArgumentException if probability is not between 0 and 1

*/

public static Graph completeBipartite(int V1, int V2) {

return bipartite(V1, V2, V1*V2);

}

/**

* Returns a random simple bipartite graph on {@code V1} and {@code V2} vertices

* with {@code E} edges.

* @param V1 the number of vertices in one partition

* @param V2 the number of vertices in the other partition

* @param E the number of edges

* @return a random simple bipartite graph on {@code V1} and {@code V2} vertices,

* containing a total of {@code E} edges

* @throws IllegalArgumentException if no such simple bipartite graph exists

*/

public static Graph bipartite(int V1, int V2, int E) {

if (E > (long) V1*V2) throw new IllegalArgumentException("Too many edges");

if (E < 0) throw new IllegalArgumentException("Too few edges");

Graph G = new Graph(V1 + V2);

int[] vertices = new int[V1 + V2];

for (int i = 0; i < V1 + V2; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

SET<Edge> set = new SET<Edge>();

while (G.E() < E) {

int i = StdRandom.uniform(V1);

int j = V1 + StdRandom.uniform(V2);

Edge e = new Edge(vertices[i], vertices[j]);

if (!set.contains(e)) {

set.add(e);

G.addEdge(vertices[i], vertices[j]);

}

}

return G;

}

/**

* Returns a random simple bipartite graph on {@code V1} and {@code V2} vertices,

* containing each possible edge with probability {@code p}.

* @param V1 the number of vertices in one partition

* @param V2 the number of vertices in the other partition

* @param p the probability that the graph contains an edge with one endpoint in either side

* @return a random simple bipartite graph on {@code V1} and {@code V2} vertices,

* containing each possible edge with probability {@code p}

* @throws IllegalArgumentException if probability is not between 0 and 1

*/

public static Graph bipartite(int V1, int V2, double p) {

if (p < 0.0 || p > 1.0)

throw new IllegalArgumentException("Probability must be between 0 and 1");

int[] vertices = new int[V1 + V2];

for (int i = 0; i < V1 + V2; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

Graph G = new Graph(V1 + V2);

for (int i = 0; i < V1; i++)

for (int j = 0; j < V2; j++)

if (StdRandom.bernoulli(p))

G.addEdge(vertices[i], vertices[V1+j]);

return G;

}

/**

* Returns a path graph on {@code V} vertices.

* @param V the number of vertices in the path

* @return a path graph on {@code V} vertices

*/

public static Graph path(int V) {

Graph G = new Graph(V);

int[] vertices = new int[V];

for (int i = 0; i < V; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

for (int i = 0; i < V-1; i++) {

G.addEdge(vertices[i], vertices[i+1]);

}

return G;

}

/**

* Returns a complete binary tree graph on {@code V} vertices.

* @param V the number of vertices in the binary tree

* @return a complete binary tree graph on {@code V} vertices

*/

public static Graph binaryTree(int V) {

Graph G = new Graph(V);

int[] vertices = new int[V];

for (int i = 0; i < V; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

for (int i = 1; i < V; i++) {

G.addEdge(vertices[i], vertices[(i-1)/2]);

}

return G;

}

/**

* Returns a cycle graph on {@code V} vertices.

* @param V the number of vertices in the cycle

* @return a cycle graph on {@code V} vertices

*/

public static Graph cycle(int V) {

Graph G = new Graph(V);

int[] vertices = new int[V];

for (int i = 0; i < V; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

for (int i = 0; i < V-1; i++) {

G.addEdge(vertices[i], vertices[i+1]);

}

G.addEdge(vertices[V-1], vertices[0]);

return G;

}

/**

* Returns an Eulerian cycle graph on {@code V} vertices.

*

* @param V the number of vertices in the cycle

* @param E the number of edges in the cycle

* @return a graph that is an Eulerian cycle on {@code V} vertices

* and {@code E} edges

* @throws IllegalArgumentException if either {@code V <= 0} or {@code E <= 0}

*/

public static Graph eulerianCycle(int V, int E) {

if (E <= 0)

throw new IllegalArgumentException("An Eulerian cycle must have at least one edge");

if (V <= 0)

throw new IllegalArgumentException("An Eulerian cycle must have at least one vertex");

Graph G = new Graph(V);

int[] vertices = new int[E];

for (int i = 0; i < E; i++)

vertices[i] = StdRandom.uniform(V);

for (int i = 0; i < E-1; i++) {

G.addEdge(vertices[i], vertices[i+1]);

}

G.addEdge(vertices[E-1], vertices[0]);

return G;

}

/**

* Returns an Eulerian path graph on {@code V} vertices.

*

* @param V the number of vertices in the path

* @param E the number of edges in the path

* @return a graph that is an Eulerian path on {@code V} vertices

* and {@code E} edges

* @throws IllegalArgumentException if either {@code V <= 0} or {@code E < 0}

*/

public static Graph eulerianPath(int V, int E) {

if (E < 0)

throw new IllegalArgumentException("negative number of edges");

if (V <= 0)

throw new IllegalArgumentException("An Eulerian path must have at least one vertex");

Graph G = new Graph(V);

int[] vertices = new int[E+1];

for (int i = 0; i < E+1; i++)

vertices[i] = StdRandom.uniform(V);

for (int i = 0; i < E; i++) {

G.addEdge(vertices[i], vertices[i+1]);

}

return G;

}

/**

* Returns a wheel graph on {@code V} vertices.

* @param V the number of vertices in the wheel

* @return a wheel graph on {@code V} vertices: a single vertex connected to

* every vertex in a cycle on {@code V-1} vertices

*/

public static Graph wheel(int V) {

if (V <= 1) throw new IllegalArgumentException("Number of vertices must be at least 2");

Graph G = new Graph(V);

int[] vertices = new int[V];

for (int i = 0; i < V; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

// simple cycle on V-1 vertices

for (int i = 1; i < V-1; i++) {

G.addEdge(vertices[i], vertices[i+1]);

}

G.addEdge(vertices[V-1], vertices[1]);

// connect vertices[0] to every vertex on cycle

for (int i = 1; i < V; i++) {

G.addEdge(vertices[0], vertices[i]);

}

return G;

}

/**

* Returns a star graph on {@code V} vertices.

* @param V the number of vertices in the star

* @return a star graph on {@code V} vertices: a single vertex connected to

* every other vertex

*/

public static Graph star(int V) {

if (V <= 0) throw new IllegalArgumentException("Number of vertices must be at least 1");

Graph G = new Graph(V);

int[] vertices = new int[V];

for (int i = 0; i < V; i++)

vertices[i] = i;

StdRandom.shuffle(vertices);

// connect vertices[0] to every other vertex

for (int i = 1; i < V; i++) {

G.addEdge(vertices[0], vertices[i]);

}

return G;

}

/**

* Returns a uniformly random {@code k}-regular graph on {@code V} vertices

* (not necessarily simple). The graph is simple with probability only about e^(-k^2/4),

* which is tiny when k = 14.

*

* @param V the number of vertices in the graph

* @param k degree of each vertex

* @return a uniformly random {@code k}-regular graph on {@code V} vertices.

*/

public static Graph regular(int V, int k) {

if (V*k % 2 != 0) throw new IllegalArgumentException("Number of vertices * k must be even");

Graph G = new Graph(V);

// create k copies of each vertex

int[] vertices = new int[V*k];

for (int v = 0; v < V; v++) {

for (int j = 0; j < k; j++) {

vertices[v + V*j] = v;

}

}

// pick a random perfect matching

StdRandom.shuffle(vertices);

for (int i = 0; i < V*k/2; i++) {

G.addEdge(vertices[2*i], vertices[2*i + 1]);

}

return G;

}

// http://www.proofwiki.org/wiki/Labeled_Tree_from_Prüfer_Sequence

// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.6484&rep=rep1&type=pdf

/**

* Returns a uniformly random tree on {@code V} vertices.

* This algorithm uses a Prufer sequence and takes time proportional to <em>V log V</em>.

* @param V the number of vertices in the tree

* @return a uniformly random tree on {@code V} vertices

*/

public static Graph tree(int V) {

Graph G = new Graph(V);

// special case

if (V == 1) return G;

// Cayley's theorem: there are V^(V-2) labeled trees on V vertices

// Prufer sequence: sequence of V-2 values between 0 and V-1

// Prufer's proof of Cayley's theorem: Prufer sequences are in 1-1

// with labeled trees on V vertices

int[] prufer = new int[V-2];

for (int i = 0; i < V-2; i++)

prufer[i] = StdRandom.uniform(V);

// degree of vertex v = 1 + number of times it appers in Prufer sequence

int[] degree = new int[V];

for (int v = 0; v < V; v++)

degree[v] = 1;

for (int i = 0; i < V-2; i++)

degree[prufer[i]]++;

// pq contains all vertices of degree 1

MinPQ<Integer> pq = new MinPQ<Integer>();

for (int v = 0; v < V; v++)

if (degree[v] == 1) pq.insert(v);

// repeatedly delMin() degree 1 vertex that has the minimum index

for (int i = 0; i < V-2; i++) {

int v = pq.delMin();

G.addEdge(v, prufer[i]);

degree[v]--;

degree[prufer[i]]--;

if (degree[prufer[i]] == 1) pq.insert(prufer[i]);

}

G.addEdge(pq.delMin(), pq.delMin());

return G;

}

/**

* Unit tests the {@code GraphGenerator} library.

*

* @param args the command-line arguments

*/

public static void main(String[] args) {

int V = Integer.parseInt(args[0]);

int E = Integer.parseInt(args[1]);

int V1 = V/2;

int V2 = V - V1;

StdOut.println("complete graph");

StdOut.println(complete(V));

StdOut.println();

StdOut.println("simple");

StdOut.println(simple(V, E));

StdOut.println();

StdOut.println("Erdos-Renyi");

double p = (double) E / (V*(V-1)/2.0);

StdOut.println(simple(V, p));

StdOut.println();

StdOut.println("complete bipartite");

StdOut.println(completeBipartite(V1, V2));

StdOut.println();

StdOut.println("bipartite");

StdOut.println(bipartite(V1, V2, E));

StdOut.println();

StdOut.println("Erdos Renyi bipartite");

double q = (double) E / (V1*V2);

StdOut.println(bipartite(V1, V2, q));

StdOut.println();

StdOut.println("path");

StdOut.println(path(V));

StdOut.println();

StdOut.println("cycle");

StdOut.println(cycle(V));

StdOut.println();

StdOut.println("binary tree");

StdOut.println(binaryTree(V));

StdOut.println();

StdOut.println("tree");

StdOut.println(tree(V));

StdOut.println();

StdOut.println("4-regular");

StdOut.println(regular(V, 4));

StdOut.println();

StdOut.println("star");

StdOut.println(star(V));

StdOut.println();

StdOut.println("wheel");

StdOut.println(wheel(V));

StdOut.println();

}

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote