import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import Heaps.GenericHeap; public class Graph { private class vertex{ HashMap nbrs=new HashMap<>(); } HashMap vertcs; public Graph(){ vertcs=new HashMap<>(); } public int numVertex() { return this.vertcs.size(); } public boolean containsVertex(String vname) { return this.vertcs.containsKey(vname); } public void addVertex(String vname) { vertex vtx=new vertex(); this.vertcs.put(vname,vtx); } public void removeVertex(String vname) { vertex vtx=this.vertcs.get(vname); ArrayList keys=new ArrayList<>(vtx.nbrs.keySet()); for(String key:keys) { vertex nbrvtx=this.vertcs.get(key); nbrvtx.nbrs.remove(vname); } this.vertcs.remove(vname); } public int numEdge() { int count=0; ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { vertex vtx=this.vertcs.get(key); count+=vtx.nbrs.size(); } return count/2; } public boolean containsEdge(String vname1,String vname2) { vertex vtx1=this.vertcs.get(vname1); vertex vtx2=this.vertcs.get(vname2); if(vtx1==null||vtx2==null||!vtx1.nbrs.containsKey(vname2)) return false; return true; } public void addEdge(String vname1,String vname2,int cost) { vertex vtx1=this.vertcs.get(vname1); vertex vtx2=this.vertcs.get(vname2); if(vtx1==null||vtx2==null||vtx1.nbrs.containsKey(vname2)) return; vtx1.nbrs.put(vname2,cost); vtx2.nbrs.put(vname1,cost); } public void removeEdge(String vname1,String vname2) { vertex vtx1=this.vertcs.get(vname1); vertex vtx2=this.vertcs.get(vname2); if(vtx1==null||vtx2==null||!vtx1.nbrs.containsKey(vname2)) return; vtx1.nbrs.remove(vname2); vtx2.nbrs.remove(vname1); } public void display() { ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { vertex vtx=this.vertcs.get(key); System.out.println(key+" := "+vtx.nbrs); } } public boolean hasPath(String source ,String dest,HashMap processed) { processed.put(source, true); if(containsEdge(source,dest)) { return true; } vertex vtx=this.vertcs.get(source); ArrayList keys=new ArrayList<>(vtx.nbrs.keySet()); for(String key:keys) { if(!processed.containsKey(key) && hasPath(key,dest,processed)) return true; } return false; } private class pair{ String vname; String psf; } public boolean bfs(String source,String dest) { // breadth first search HashMap processed=new HashMap<>(); LinkedList queue=new LinkedList<>(); pair sp=new pair(); sp.vname=source; sp.psf=source; queue.addLast(sp); while(!queue.isEmpty()) { pair rp=queue.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); if(containsEdge(rp.vname,dest)) { System.out.println(rp.psf+dest); return true; } vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; queue.addLast(np); } } } return false; } public boolean dfs(String source,String dest) { //deapth first search LinkedList stack=new LinkedList<>(); HashMap processed=new HashMap<>(); pair sp=new pair(); sp.vname=source; sp.psf=source; stack.addFirst(sp); while(!stack.isEmpty()) { pair rp=stack.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); if(containsEdge(rp.vname,dest)) { System.out.println(rp.psf+dest); return true; } vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; stack.addFirst(np); } } } return false; } public void bft() { //breadth first traversal HashMap processed=new HashMap<>(); LinkedList queue=new LinkedList<>(); ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { if(processed.containsKey(key)) continue; pair sp=new pair(); sp.vname=key; sp.psf=key; queue.addLast(sp); while(!queue.isEmpty()) { pair rp=queue.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); System.out.println(rp.vname+" via "+rp.psf); vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; queue.addLast(np); } } } } } public void dft() { //deapt first traversal HashMap processed=new HashMap<>(); LinkedList stack=new LinkedList<>(); ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { pair sp=new pair(); sp.vname=key; sp.psf=key; stack.addFirst(sp); while(!stack.isEmpty()) { pair rp=stack.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); System.out.println(rp.vname+" via "+rp.psf); vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; stack.addFirst(np); } } } } } public boolean isCyclic() { HashMap processed=new HashMap<>(); LinkedList queue=new LinkedList<>(); ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { if(processed.containsKey(key)) continue; pair sp=new pair(); sp.vname=key; sp.psf=key; queue.addLast(sp); while(!queue.isEmpty()) { pair rp=queue.removeFirst(); if(processed.containsKey(rp.vname)) return true; processed.put(rp.vname,true); vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; queue.addLast(np); } } } } return false; } public boolean isConnected() { int flag=0; HashMap processed=new HashMap<>(); LinkedList queue=new LinkedList<>(); ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { if(processed.containsKey(key)) continue; flag++; pair sp=new pair(); sp.vname=key; sp.psf=key; queue.addLast(sp); while(!queue.isEmpty()) { pair rp=queue.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; queue.addLast(np); } } } } if(flag>=2) return false; else return true; } public boolean isTree() { return !isCyclic()&&isConnected(); } public ArrayList> getConnectedComp() { ArrayList> ans=new ArrayList<>(); HashMap processed=new HashMap<>(); LinkedList queue=new LinkedList<>(); ArrayList keys=new ArrayList<>(this.vertcs.keySet()); for(String key:keys) { if(processed.containsKey(key)) continue; ArrayList subans=new ArrayList<>(); pair sp=new pair(); sp.vname=key; sp.psf=key; queue.addLast(sp); while(!queue.isEmpty()) { pair rp=queue.removeFirst(); if(processed.containsKey(rp.vname)) continue; processed.put(rp.vname,true); subans.add(rp.vname); vertex vtx=this.vertcs.get(rp.vname); ArrayList nbrs=new ArrayList<>(vtx.nbrs.keySet()); for(String nbr:nbrs) { if(!processed.containsKey(nbr)) { pair np=new pair(); np.vname=nbr; np.psf=rp.psf+nbr; queue.addLast(np); } } } ans.add(subans); } return ans; } private class PrimsPair implements Comparable{ String vname; String acqvname; int cost; public int compareTo(PrimsPair o) { return o.cost-this.cost; } } public Graph prims() { HashMap map=new HashMap<>(); GenericHeap heap=new GenericHeap<>(); Graph mst=new Graph(); for(String vrtx:this.vertcs.keySet()) { PrimsPair np=new PrimsPair(); np.acqvname=null; np.vname=vrtx; np.cost=Integer.MAX_VALUE; heap.add(np); map.put(vrtx, np); } while(!heap.isEmpty()) { PrimsPair rp=heap.remove(); map.remove(rp.vname); if(rp.acqvname==null) { mst.addVertex(rp.vname); }else { mst.addVertex(rp.vname); mst.addEdge(rp.vname, rp.acqvname, rp.cost); } for(String nbr:this.vertcs.get(rp.vname).nbrs.keySet()) { if(map.containsKey(nbr)) { //old cost that is from diff path stored in map int oc=map.get(nbr).cost; // cost that present vname need cost to go to nbr int nc=this.vertcs.get(rp.vname).nbrs.get(nbr); if(nc{ String vname; String psf; int cost; public int compareTo(DijktsraPair o) { return o.cost-this.cost; } } public HashMap Dijktsra(String source) { HashMap map=new HashMap<>(); GenericHeap heap=new GenericHeap<>(); HashMap ans =new HashMap<>(); for(String vrtx:this.vertcs.keySet()) { DijktsraPair np=new DijktsraPair(); np.psf=""; np.vname=vrtx; np.cost=Integer.MAX_VALUE; if(vrtx==source) { np.cost=0; np.psf=source; } heap.add(np); map.put(vrtx, np); } while(!heap.isEmpty()) { DijktsraPair rp=heap.remove(); map.remove(rp.vname); ans.put(rp.vname,rp.cost); for(String nbr:this.vertcs.get(rp.vname).nbrs.keySet()) { if(map.containsKey(nbr)) { //old cost that is from diff path stored in map int oc=map.get(nbr).cost; // cost that present vname need cost to go to nbr int nc=rp.cost+this.vertcs.get(rp.vname).nbrs.get(nbr); if(nc