Euclidean graphs Design and implement an API EuclideanGraph
Euclidean graphs. Design and implement an API EuclideanGraph for graphs
 whose vertices are points in the plane that include coordinates. Include a method
 show() that uses StdDraw to draw the graph. please give solution in java
Solution
 import java.awt.Point;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Queue;
 import java.util.Scanner;
import edu.princeton.cs.algs4.StdDraw;
public class EuclideanGraph {
    private HashMap<String, Integer> st; // string -> index
    private String[] keys;           // index -> string
    private Graph G;
    private Point[] points;
    private boolean[] marked;
   public EuclideanGraph(String filename, String delimiter) throws FileNotFoundException {
        st = new HashMap<>();
       // First pass builds the index by reading strings to associate
        // distinct strings with an index
        Scanner in = new Scanner(new File(filename));
        while (in.hasNextLine()) {
            String point = in.next();
            System.out.println(point);
            if (!st.containsKey(point))
                st.put(point, st.size());
       }
        System.out.println(\"Done reading \" + filename);
       // inverted index to get string keys in an array
        keys = new String[st.size()];
        for (String name : st.keySet()) {
            keys[st.get(name)] = name;
        }
       // convert string to Point
        points = new Point[st.size()];
        for (int i = 0; i < st.size(); i++) {
            int loc = keys[i].indexOf(\",\");
            int x = Integer.parseInt(keys[i].substring(1, loc));
            int y = Integer.parseInt(keys[i].substring(loc + 1, keys[i].length() - 1));
            points[i] = new Point(x,y);
        }
       // second pass builds the graph by connecting first vertex on each
        // line to all others
        G = new Graph(st.size());
        in = new Scanner(new File(filename));
        while (in.hasNextLine()) {
            String x = in.next();
            int v = st.get(x);
            String y = in.next();
            int w = st.get(y);
            G.addEdge(v, w);
            G.addEdge(w, v);
        }
        in.close();
    }
   public void show() {
        StdDraw.setScale(-1, 10);
        marked = new boolean[G.V()];
        for (int v = 0; v < G.V(); v++) {
            if (!marked[v])
                bfs(v);
        }
    }
   private void bfs(int s) {
        Queue<Integer> Q = new LinkedList<>();
        marked[s] = true;
        Q.add(s);
        while (!Q.isEmpty()) {
            int v = Q.poll();
            StdDraw.setPenRadius(0.02);
            StdDraw.point(points[v].getX(), points[v].getY());
            for (int w : G.adj(v)) {
                StdDraw.setPenRadius();
                StdDraw.line(points[v].getX(), points[v].getY(), points[w].getX(), points[w].getY());
                if (!marked[w]) {
                    marked[w] = true;
                    Q.add(w);
                }
            }
        }
    }
   public static void main(String[] args) throws FileNotFoundException {
        String filename = args[0];
        EuclideanGraph G = new EuclideanGraph(filename, \" \");
        G.show();
    }
 }
Graph.java
import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Scanner;
 import java.util.Stack;
public class Graph {
    private static final String NEWLINE = System.getProperty(\"line.separator\");
   private int V;
    private int E;
    private List<List<Integer>> adj;
   public Graph(int V) {
        if (V < 0) throw new IllegalArgumentException(\"Number of vertices must be nonnegative\");
        this.V = V;
        this.E = 0;
        adj = new ArrayList<List<Integer>>(V);
        for (int v = 0; v < V; v++) {
            List<Integer> list = new LinkedList<Integer>();
            adj.add(list);
        }
    }
   public Graph(Scanner in) {
        this(in.nextInt());
        int E = in.nextInt();
        if (E < 0) throw new IllegalArgumentException(\"Number of edges must be nonnegative\");
        for (int i = 0; i < E; i++) {
            int v = in.nextInt();
            int w = in.nextInt();
            addEdge(v, w);
        }
    }
   public int V() {
        return V;
    }
   public int E() {
        return E;
    }
   private void validateVertex(int v) {
        if (v < 0 || v >= V)
            throw new IndexOutOfBoundsException(\"vertex \" + v + \" is not between 0 and \" + (V-1));
    }
   public void addEdge(int v, int w) {
        validateVertex(v);
        validateVertex(w);
        E++;
        adj.get(v).add(w);
        adj.get(w).add(v);
    }
   public Iterable<Integer> adj(int v) {
        validateVertex(v);
        return adj.get(v);
    }
   public int degree(int v) {
        validateVertex(v);
        return adj.get(v).size();
    }
   /**
    * Ex 4.1.3
    * deep copy
    */
    public Graph(Graph G) {
        this(G.V());
        this.E = G.E();
        for (int v = 0; v < G.V(); v++) {
            for (int w : G.adj.get(v))
                this.adj.get(v).add(w);
        }
    }
   /**
    * Ex 4.1.4
    * Add a method hasEdge()
    */
    public boolean hasEdge(int v, int w) {
        for (int u : adj.get(v))
            if (u == w)
                return true;
        return false;
    }
   /**
    * Ex 4.1.5
    * disallow parallel edges and self-loops.
    */
    public void validateEdge(int v, int w) throws Exception {
        if (v == w)
            throw new Exception(\"vertex \" + v + \" has self-loop\");
        for (int u : this.adj.get(v))
            if (u == w)
                throw new Exception(\"vertex \" + v + \" has parallel edge\");
    }
   /**
    * Ex 4.1.7
    * Returns a string representation of this graph.
    */
    public String toString() {
        StringBuilder s = new StringBuilder();
        s.append(V + \" vertices, \" + E + \" edges \" + NEWLINE);
        for (int v = 0; v < V; v++) {
            s.append(v + \": \");
            for (int w : adj.get(v)) {
                s.append(w + \" \");
            }
            s.append(NEWLINE);
        }
        return s.toString();
    }
   /**
    * Ex 4.1.8
    * Search API
    */
    public class Search {
        private int s;
        private WeightedQuickUnionUF uf;
       /**
        * find vertices connected to a source vertex s
        * The constructor can build a UF object, do a union() operation
        * for each of the graph’s edges.
        */
        public Search(Graph G, int s) {
            this.s = s;
            this.uf = new WeightedQuickUnionUF(G.V());
            for (int v = 0; v < G.V(); v++) {
                for (int w : G.adj.get(v)) {
                    if (uf.connected(v, w))
                        continue;
                    uf.union(v, w);
                }
            }
        }
       /**
        * is v connected to s?
        * Implement marked(v) by calling connected(s, v)
        */
        boolean marked(int v) {
            return uf.connected(s, v);
        }
       int count() {
            return uf.count(s);
        }
}
   public List<Integer> non_articulation_vertex() {
        vertexClassification();
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < V; i++) {
            if (!articulation[i])
                list.add(i);
            System.out.println(i + \" \" + disc[i] + \"/\" + low[i]);
        }
        return list;
    }
   private boolean[] articulation;
    private int time;
    private int[] disc;
    private int[] low;
   public void vertexClassification() {
        articulation = new boolean[this.V()];
        disc = new int[this.V()];
        low = new int[this.V()];
        Arrays.fill(disc, -1);
        Arrays.fill(low, -1);
        time = 0;
        for (int v = 0; v < this.V(); v++) {
            if (disc[v] == -1)
                dfs_ap(v, v);
        }
    }
   private void dfs_ap(int parent, int cur_v) {
        int children = 0;
        disc[cur_v] = time++;
        low[cur_v] = disc[cur_v];
        for (int neib : adj.get(cur_v)) {
            if (disc[neib] == -1) {
                children++;
                dfs_ap(cur_v, neib);
                // update low number
                low[cur_v] = Math.min(low[cur_v], low[neib]);
                // non-root of DFS is an articulation point if low[neib] >= disc[cur_v]
                if (low[neib] >= disc[cur_v] && parent != cur_v)
                    articulation[cur_v] = true;
            }
            // update low number - ignore reverse of edge leading to cur_v
            else if (neib != parent)
                low[cur_v] = Math.min(low[cur_v], disc[neib]);
        }
        // root of DFS is an articulation point if it has more than 1 child
        if (parent == cur_v && children > 1)
            articulation[cur_v] = true;
    }
   public Graph(Scanner in, String sp) {
        this(in.nextInt());       // calls Graph(V)
        this.E = in.nextInt();
        if (E < 0) throw new IllegalArgumentException(\"Number of edges must be nonnegative\");
        in.nextLine();
        List<Stack<Integer>> stacks = new ArrayList<>();
        for (int i = 0; i < V; i++)
            stacks.add(new Stack<Integer>());
        while (in.hasNextLine())
        {
            String[] arr = in.nextLine().split(sp);
            int v = Integer.parseInt(arr[0]);
            for (int i = 1; i < arr.length; i++) {
                int w = Integer.parseInt(arr[i]);
                stacks.get(v).push(w);
                stacks.get(w).push(v);
            }
        }
        for (int i = 0; i < V; i++) {
            Stack<Integer> stack = stacks.get(i);
            while (!stack.isEmpty())
                adj.get(i).add(stack.pop());
        }
    }
   public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File(args[0]));
        Graph G = new Graph(in);
        System.out.println(G);
        // test for ex 4.1.3
        Graph G2 = new Graph(G);
        System.out.println(G2);
        // test for ex 4.1.4
        System.out.println(\"The path \" + (G.hasEdge(2,11) ? \"exists\" : \"does not exist\"));
        // test for ex 4.1.8
        Search search = G.new Search(G, 0);
        System.out.println(search.marked(10));
        System.out.println(search.marked(8));
        System.out.println(search.count());
        // test for ex 4.1.10
        in = new Scanner(new File(args[1]));
        Graph G3 = new Graph(in);
        System.out.println(G3.non_articulation_vertex());
        // test for ex 4.1.13
        BFS bfs = new BFS(G, 0);
        System.out.println(bfs.distTo(3));
        System.out.println(bfs.distTo(10));
        // test for ex 4.1.15
        in = new Scanner(new File(args[2]));
        Graph G4 = new Graph(in, \" \");
        System.out.println(G4);
        // test for ex 4.1.16
        in = new Scanner(new File(args[3]));
        Graph G5 = new Graph(in);
        GraphProperties gp = new GraphProperties(G5);
        System.out.println(\"diameter: \" + gp.diameter() + \" radius: \" + gp.radius() + \" center: \" + gp.center());
        // test for ex 4.1.17
        System.out.println(\"wiener: \" + gp.wiener());
        // test for ex 4.1.18
        System.out.println(\"girth: \" + gp.girth());
    }
}
 WeightedQuickUnionUF.java
 
 
 import java.util.Scanner;
public class WeightedQuickUnionUF {
    private int[] parent;   // parent[i] = parent of i
    private int[] size;     // size[i] = number of sites in subtree rooted at i
    private int count;      // number of components
   public WeightedQuickUnionUF(int N) {
        count = N;
        parent = new int[N];
        size = new int[N];
        for (int i = 0; i < N; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }
   public int count() {
        return count;
    }
   public int count(int p) {
        return size[find(p)];
    }
   public int find(int p) {
        validate(p);
        while (p != parent[p])
            p = parent[p];
        return p;
    }
   private void validate(int p) {
        int N = parent.length;
        if (p < 0 || p >= N) {
            throw new IndexOutOfBoundsException(\"index \" + p + \" is not between 0 and \" + (N-1));
        }
    }
   public boolean connected(int p, int q) {
        return find(p) == find(q);
    }
   public void union(int p, int q) {
        int rootP = find(p);
        int rootQ = find(q);
        if (rootP == rootQ) return;
       // make smaller root point to larger one
        if (size[rootP] < size[rootQ]) {
            parent[rootP] = rootQ;
            size[rootQ] += size[rootP];
        }
        else {
            parent[rootQ] = rootP;
            size[rootP] += size[rootQ];
        }
        count--;
    }
   public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
        while (!in.hasNext()) {
            int p = in.nextInt();
            int q = in.nextInt();
            if (uf.connected(p, q)) continue;
            uf.union(p, q);
            System.out.println(p + \" \" + q);
        }
        System.out.println(uf.count() + \" components\");
        in.close();
    }
}
 BFS.java
 
 
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.LinkedList;
 import java.util.Queue;
/**
 * Ex 4.1.13
 * Add a distTo() method
 */
 public class BFS {
    private int[] distTo;       // distTo[v] = number of edges shortest s-v path
    private int[] edgeTo;       // edgeTo[v] = previous edge on shortest s-v path
    private boolean[] marked;
    public BFS(Graph G, int s) {
        marked = new boolean[G.V()];
        distTo = new int[G.V()];
        edgeTo = new int[G.V()];
        bfs(G, s);
    }
   private void bfs(Graph G, int s) {
        Queue<Integer> q = new LinkedList<Integer>();
        for (int v = 0; v < G.V(); v++)
            distTo[v] = Integer.MAX_VALUE;
        distTo[s] = 0;
        marked[s] = true;
        q.add(s);
        while(!q.isEmpty()) {
            int v = q.poll();
            for (int w : G.adj(v)) {
                if (!marked[w]) {
                    edgeTo[w] = v;
                    distTo[w] = distTo[v] + 1;
                    marked[w] = true;
                    q.add(w);
                }
            }
        }
    }
   public int distTo(int v) {
        return distTo[v];
    }
   public boolean hasPathTo(int v) {
        return marked[v];
    }
   public Iterable<Integer> pathTo(int v) {
        if (!hasPathTo(v)) return null;
        Deque<Integer> path = new ArrayDeque<Integer>();
        int x;
        for (x = v; distTo[x] != 0; x = edgeTo[x])
            path.push(x);
        path.push(x);
        return path;
    }
 }
GraphProperties.java
 
 
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
public class GraphProperties {
    private Graph G;
    private int[] e;
    private int diam;
    private int rad;
    private boolean[] marked;
    private int[] dist;
    private int[] parent;
   /**
    * Ex 4.1.16
    * The eccentricity of a vertex
    */
    GraphProperties(Graph G) {
        this.G = G;
        e = new int[G.V()];
        diam = Integer.MIN_VALUE;
        rad = Integer.MAX_VALUE;
        marked = new boolean[G.V()];
        for (int v = 0; v < G.V(); v++) {
            Arrays.fill(marked, false);
            e[v] = BFS(G, v);
            diam = Math.max(diam, e[v]);
            rad = Math.min(rad, e[v]);
            if (v % 10000 == 0)
                System.out.print(\"\ processing vertex \" + v);
            else if (v % 100 == 0)
                System.out.print(\".\");
       }
    }
   private int BFS(Graph G, int s) {
        int max = 0;
        int[] dist = new int[G.V()];
        marked[s] = true;
        Queue<Integer> q = new LinkedList<>();
        q.add(s);
        while (!q.isEmpty()) {
            int v = q.poll();
            for (int w : G.adj(v)) {
                if (!marked[w]) {
                    dist[w] = dist[v] + 1;
                    q.add(w);
                    marked[w] = true;
                }
            }
        }
        for (int i = 0; i < dist.length; i++)
            max = Math.max(max, dist[i]);
        return max;
    }
   public int diameter() {
        return diam;
    }
   public int radius() {
        return rad;
    }
   public List<Integer> center() {
        List<Integer> list = new LinkedList<>();
        for (int v = 0; v < G.V(); v++)
            if (e[v] == radius())
                list.add(v);
        return list;
    }
   /**
    * Ex 4.1.17
    * The Wiener index of a graph
    */
    public int wiener() {
        int sum = 0;
        for (int s = 0; s < G.V(); s++) {       // BFS from each vertex
            marked = new boolean[G.V()];
            dist = new int[G.V()];
            Queue<Integer> q = new LinkedList<>();
            q.add(s);
            dist[s] = 0;
            marked[s] = true;
            while (!q.isEmpty()) {
                int v = q.poll();
                for (int w : G.adj(v)) {
                    if (!marked[w]) {
                        dist[w] = dist[v] + 1;
                        q.add(w);
                        marked[w] = true;
                        sum += dist[w];
                    }
                }
            }
        }
        return sum / 2;       // we sum the distance twice
    }
   /**
    * 4.1.18
    * The girth of a graph
    */
    public int girth() {
        int girth = Integer.MAX_VALUE;
        for (int s = 0; s < G.V(); s++) {       // BFS from each vertex
            int circle = -1;
            marked = new boolean[G.V()];
            dist = new int[G.V()];
            parent = new int[G.V()];
            Queue<Integer> q = new LinkedList<>();
            q.add(s);
            dist[s] = 0;
            parent[s] = s;
            marked[s] = true;
            while (!q.isEmpty()) {
                int v = q.poll();
                for (int w : G.adj(v)) {
                    if (!marked[w]) {
                        dist[w] = dist[v] + 1;
                        parent[w] = v;
                        q.add(w);
                        marked[w] = true;
                    } else if (w != parent[v]) {
                        circle = dist[v] + dist[w] + 1;
                        break;
                    }
                }
                if (circle > 0) break;       // found a circle
            }
            girth = Math.min(girth, circle);
        }
        return girth;
    }
 }
 euclidean.txt
(0,0) (1,1)
 (1,1) (2,2)
 (2,2) (2,0)











