aboutsummaryrefslogtreecommitdiff
path: root/com/example/portfolio3/Graphs.java
blob: 54cad9e322ca844d18d6e5b047754d97da2faa62 (plain)
  1. import java.util.*;
  2. public class Graphs {}
  3. class Vertex{
  4. private String name;
  5. public String name(){return name;}
  6. public Vertex(String s){name=s;}
  7. public String toString(){return name;}
  8. }
  9. class Edge{
  10. private Vertex from,to;
  11. private int weight;
  12. public Vertex from(){return from;}
  13. public Vertex to(){return to;}
  14. public int weight(){return weight;}
  15. Edge(Vertex from,Vertex to,int w){this.from=from; this.to=to; weight=w;}
  16. public String toString(){return from.name()+" - "+weight+" -> "+to.name(); }
  17. }
  18. interface Graph {
  19. void insertEdge(String v, String u, int w);
  20. Collection<Vertex> vertices();
  21. Collection<Edge> edges();
  22. Collection<Edge> outEdge(Vertex v);
  23. Integer getWeight(Vertex v1, Vertex v2);
  24. }
  25. abstract class AbstractGraph implements Graph{
  26. private HashMap<String,Vertex> vertexMap=new HashMap<>();
  27. private HashSet<Vertex> vertexSet=new HashSet<>();
  28. public Vertex vertex(String s){
  29. if(vertexMap.containsKey(s))return vertexMap.get(s);
  30. Vertex v=new Vertex(s);
  31. vertexMap.put(s,v);
  32. vertexSet.add(v);
  33. return v;
  34. }
  35. public void insertEdge(String v, String u, int w){
  36. insertEdge(vertex(v),vertex(u),w);
  37. }
  38. public Collection<Vertex> vertices() { return vertexSet; }
  39. //
  40. abstract public void insertEdge(Vertex v1, Vertex v2, int w);
  41. abstract public Collection<Edge> edges();
  42. abstract public Collection<Edge> outEdge(Vertex v);
  43. abstract public Integer getWeight(Vertex v1, Vertex v2);
  44. }
  45. //--------------------------------------------------------
  46. // EdgeGraph - One big set of all edges in the graph
  47. class EdgeGraph extends AbstractGraph {
  48. Set<Edge> edges=new HashSet<>();
  49. public void insertEdge(Vertex v1,Vertex v2,int w){
  50. edges.add(new Edge(v1,v2,w));
  51. }
  52. public Collection<Edge> edges(){return edges;}
  53. public Collection<Edge> outEdge(Vertex v){
  54. ArrayList<Edge> outEdge=new ArrayList<>();
  55. for(Edge e:edges)if(e.from()==v)outEdge.add(e);
  56. return outEdge;
  57. }
  58. public Integer getWeight(Vertex v1,Vertex v2){
  59. // linear in number of edges in the graph
  60. for(Edge e:edges){
  61. if(e.from()==v1 && e.to()==v2)return e.weight();
  62. }
  63. return null;
  64. }
  65. }
  66. //--------------------------------------------------------
  67. // Adjecency List Graph - A map from vertices to set of outedges from the vertex
  68. class AdjListGraph extends AbstractGraph {
  69. private Map<Vertex,Set<Edge>> outEdge= new HashMap<>();
  70. public void insertEdge(Vertex v1,Vertex v2,int w){
  71. Edge e=new Edge(v1,v2,w);
  72. if(!outEdge.containsKey(e.from()))
  73. outEdge.put(e.from(),new HashSet<Edge>());
  74. outEdge.get(e.from()).add(e);
  75. }
  76. public Collection<Edge> edges(){
  77. Set<Edge> edges=new HashSet<>();
  78. for(Vertex v:outEdge.keySet())edges.addAll(outEdge.get(v));
  79. return edges;
  80. }
  81. public Collection<Edge> outEdge(Vertex v){
  82. if(!outEdge.containsKey(v))
  83. return new HashSet<Edge>();
  84. return outEdge.get(v);
  85. }
  86. public Integer getWeight(Vertex v1,Vertex v2){
  87. // linear in number of outedges from vertices
  88. if(!outEdge.containsKey(v1))return null;
  89. for(Edge e:outEdge.get(v1)){
  90. if(e.to()==v2)return e.weight();
  91. }
  92. return null;
  93. }
  94. }
  95. //--------------------------------------------------------
  96. // Adjecency Map Graph - A map from vertices to map of target vertex to edge
  97. class AdjMapGraph extends AbstractGraph {
  98. private Map<Vertex, Map<Vertex, Edge>> outEdge = new HashMap<>();
  99. public void insertEdge(Vertex v1, Vertex v2, int w) {
  100. Edge e = new Edge(v1,v2, w);
  101. if (!outEdge.containsKey(e.from()))
  102. outEdge.put(e.from(), new HashMap<Vertex, Edge>());
  103. outEdge.get(e.from()).put(e.to(), e);
  104. }
  105. public Collection<Edge> edges() {
  106. Set<Edge> edges = new HashSet<>();
  107. for (Vertex v : outEdge.keySet())
  108. for (Vertex w : outEdge.get(v).keySet())
  109. edges.add(outEdge.get(v).get(w));
  110. return edges;
  111. }
  112. public Collection<Edge> outEdge(Vertex v) {
  113. return outEdge.get(v).values();
  114. }
  115. public Integer getWeight(Vertex v1, Vertex v2) {
  116. // constant time operation
  117. if(!outEdge.containsKey(v1))return null;
  118. if(!outEdge.get(v1).containsKey(v2))return null;
  119. return outEdge.get(v1).get(v2).weight();
  120. }
  121. }
  122. //--------------------------------------------------------
  123. // Matrix Graph: weights are stored in a twodimensional array
  124. class MatrixGraph extends AbstractGraph {
  125. private Integer[][] matrix=null; // made in constructor
  126. // We must be able to map vertices to index in matrix and back again
  127. private Vertex[] index2vertex; // made in constructor
  128. private Map<Vertex,Integer> vertex2index=new HashMap<>();
  129. private int numVertex; // maximum number of vertices
  130. MatrixGraph(int numVertex){ // maximum number of vertices allowed
  131. this.numVertex=numVertex;
  132. matrix =new Integer[numVertex][numVertex];
  133. index2vertex=new Vertex[numVertex];
  134. }
  135. private int getIndex(Vertex v){
  136. if(vertex2index.containsKey(v)) return vertex2index.get(v);
  137. int index=vertex2index.size();
  138. if(index>=index2vertex.length)throw new RuntimeException("Too many vertices in graph");
  139. vertex2index.put(v,index);
  140. index2vertex[index]=v;
  141. return index;
  142. }
  143. public void insertEdge(Vertex v1,Vertex v2,int w){
  144. matrix[getIndex(v1)][getIndex(v2)] = w;
  145. }
  146. public Collection<Edge> edges(){
  147. HashSet<Edge> edges=new HashSet<>();
  148. for(int i=0;i<numVertex;i++){
  149. for(int j=0;j<numVertex;j++){
  150. Integer weight=matrix[i][j]; // may be null
  151. if(weight==null)continue;
  152. edges.add(new Edge(index2vertex[i],index2vertex[j],weight));
  153. }
  154. }
  155. return edges;
  156. }
  157. public Collection<Edge> outEdge(Vertex v1){
  158. HashSet<Edge> edges=new HashSet<>();
  159. int i=vertex2index.get(v1);
  160. for(int j=0;j<numVertex;j++){
  161. Integer weight=matrix[i][j]; // may be null
  162. if(weight==null)continue;
  163. edges.add(new Edge(v1,index2vertex[j],weight));
  164. }
  165. return edges;
  166. }
  167. public Integer getWeight(Vertex v1,Vertex v2){
  168. // constant time operation
  169. return matrix[vertex2index.get(v1)][vertex2index.get(v2)];}
  170. }