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