aboutsummaryrefslogtreecommitdiff
path: root/com/example/portfolio3/Graphs.java
blob: 639c4fdcbae89ffa114dacc4999d1bed4612a69d (plain)
  1. package com.example.portfolio3;
  2. // origin: <https://moodle.ruc.dk/course/section.php?id=211877>
  3. import java.util.*;
  4. /// foo
  5. public class Graphs {}
  6. /// foo
  7. class Vertex{
  8. /// foo
  9. private String name;
  10. /// foo
  11. /// @return String
  12. public String name(){return name;}
  13. /// foo
  14. /// @param s foo
  15. public Vertex(String s){name=s;}
  16. /// foo
  17. /// @return String
  18. public String toString(){return name;}
  19. }
  20. /// foo
  21. class Edge{
  22. /// foo
  23. private Vertex from,to;
  24. /// foo
  25. private int weight;
  26. /// foo
  27. /// @return Vertex
  28. public Vertex from(){return from;}
  29. /// foo
  30. /// @return Vertex
  31. public Vertex to(){return to;}
  32. /// foo
  33. /// @return int
  34. public int weight(){return weight;}
  35. /// foo
  36. /// @param from foo
  37. /// @param to foo
  38. /// @param w foo
  39. Edge(Vertex from,Vertex to,int w){this.from=from; this.to=to; weight=w;}
  40. /// foo
  41. /// @return String
  42. public String toString(){return from.name()+" - "+weight+" -> "+to.name(); }
  43. }
  44. /// foo
  45. interface Graph {
  46. /// foo
  47. /// @param v foo
  48. /// @param u foo
  49. /// @param w foo
  50. void insertEdge(String v, String u, int w);
  51. /// foo
  52. /// @return Collection
  53. Collection<Vertex> vertices();
  54. /// foo
  55. /// @return Collection
  56. Collection<Edge> edges();
  57. /// foo
  58. /// @param v foo
  59. /// @return Collection
  60. Collection<Edge> outEdge(Vertex v);
  61. /// foo
  62. /// @param v1 foo
  63. /// @param v2 foo
  64. /// @return Integer
  65. Integer getWeight(Vertex v1, Vertex v2);
  66. }
  67. /// foo
  68. abstract class AbstractGraph implements Graph{
  69. /// foo
  70. private HashMap<String,Vertex> vertexMap=new HashMap<>();
  71. /// foo
  72. private HashSet<Vertex> vertexSet=new HashSet<>();
  73. /// foo
  74. /// @param s foo
  75. /// @return Vertex
  76. public Vertex vertex(String s){
  77. if(vertexMap.containsKey(s))return vertexMap.get(s);
  78. Vertex v=new Vertex(s);
  79. vertexMap.put(s,v);
  80. vertexSet.add(v);
  81. return v;
  82. }
  83. /// foo
  84. public void insertEdge(String v, String u, int w){
  85. insertEdge(vertex(v),vertex(u),w);
  86. }
  87. /// foo
  88. public Collection<Vertex> vertices() { return vertexSet; }
  89. /// foo
  90. /// @param v1 foo
  91. /// @param v2 foo
  92. /// @param w foo
  93. abstract public void insertEdge(Vertex v1, Vertex v2, int w);
  94. /// foo
  95. abstract public Collection<Edge> edges();
  96. /// foo
  97. abstract public Collection<Edge> outEdge(Vertex v);
  98. /// foo
  99. abstract public Integer getWeight(Vertex v1, Vertex v2);
  100. }
  101. /// EdgeGraph - One big set of all edges in the graph
  102. class EdgeGraph extends AbstractGraph {
  103. /// foo
  104. Set<Edge> edges=new HashSet<>();
  105. /// foo
  106. public void insertEdge(Vertex v1,Vertex v2,int w){
  107. edges.add(new Edge(v1,v2,w));
  108. }
  109. /// foo
  110. public Collection<Edge> edges(){return edges;}
  111. /// foo
  112. public Collection<Edge> outEdge(Vertex v){
  113. ArrayList<Edge> outEdge=new ArrayList<>();
  114. for(Edge e:edges)if(e.from()==v)outEdge.add(e);
  115. return outEdge;
  116. }
  117. /// foo
  118. public Integer getWeight(Vertex v1,Vertex v2){
  119. // linear in number of edges in the graph
  120. for(Edge e:edges){
  121. if(e.from()==v1 && e.to()==v2)return e.weight();
  122. }
  123. return null;
  124. }
  125. }
  126. //--------------------------------------------------------
  127. // Adjecency List Graph - A map from vertices to set of outedges from the vertex
  128. /// foo
  129. class AdjListGraph extends AbstractGraph {
  130. /// foo
  131. private Map<Vertex,Set<Edge>> outEdge= new HashMap<>();
  132. /// foo
  133. public void insertEdge(Vertex v1,Vertex v2,int w){
  134. Edge e=new Edge(v1,v2,w);
  135. if(!outEdge.containsKey(e.from()))
  136. outEdge.put(e.from(),new HashSet<Edge>());
  137. outEdge.get(e.from()).add(e);
  138. }
  139. /// foo
  140. public Collection<Edge> edges(){
  141. Set<Edge> edges=new HashSet<>();
  142. for(Vertex v:outEdge.keySet())edges.addAll(outEdge.get(v));
  143. return edges;
  144. }
  145. /// foo
  146. public Collection<Edge> outEdge(Vertex v){
  147. if(!outEdge.containsKey(v))
  148. return new HashSet<Edge>();
  149. return outEdge.get(v);
  150. }
  151. /// foo
  152. public Integer getWeight(Vertex v1,Vertex v2){
  153. // linear in number of outedges from vertices
  154. if(!outEdge.containsKey(v1))return null;
  155. for(Edge e:outEdge.get(v1)){
  156. if(e.to()==v2)return e.weight();
  157. }
  158. return null;
  159. }
  160. }
  161. //--------------------------------------------------------
  162. // Adjecency Map Graph - A map from vertices to map of target vertex to edge
  163. /// foo
  164. class AdjMapGraph extends AbstractGraph {
  165. /// foo
  166. private Map<Vertex, Map<Vertex, Edge>> outEdge = new HashMap<>();
  167. /// foo
  168. public void insertEdge(Vertex v1, Vertex v2, int w) {
  169. Edge e = new Edge(v1,v2, w);
  170. if (!outEdge.containsKey(e.from()))
  171. outEdge.put(e.from(), new HashMap<Vertex, Edge>());
  172. outEdge.get(e.from()).put(e.to(), e);
  173. }
  174. /// foo
  175. public Collection<Edge> edges() {
  176. Set<Edge> edges = new HashSet<>();
  177. for (Vertex v : outEdge.keySet())
  178. for (Vertex w : outEdge.get(v).keySet())
  179. edges.add(outEdge.get(v).get(w));
  180. return edges;
  181. }
  182. /// foo
  183. public Collection<Edge> outEdge(Vertex v) {
  184. return outEdge.get(v).values();
  185. }
  186. /// foo
  187. public Integer getWeight(Vertex v1, Vertex v2) {
  188. // constant time operation
  189. if(!outEdge.containsKey(v1))return null;
  190. if(!outEdge.get(v1).containsKey(v2))return null;
  191. return outEdge.get(v1).get(v2).weight();
  192. }
  193. }
  194. //--------------------------------------------------------
  195. // Matrix Graph: weights are stored in a twodimensional array
  196. /// foo
  197. class MatrixGraph extends AbstractGraph {
  198. /// foo
  199. private Integer[][] matrix=null; // made in constructor
  200. /// foo
  201. // We must be able to map vertices to index in matrix and back again
  202. private Vertex[] index2vertex; // made in constructor
  203. /// foo
  204. private Map<Vertex,Integer> vertex2index=new HashMap<>();
  205. /// foo
  206. private int numVertex; // maximum number of vertices
  207. /// foo
  208. /// @param numVertex maximum number of vertices allowed
  209. MatrixGraph(int numVertex){
  210. this.numVertex=numVertex;
  211. matrix =new Integer[numVertex][numVertex];
  212. index2vertex=new Vertex[numVertex];
  213. }
  214. /// foo
  215. /// @param v vertex
  216. /// @return int
  217. private int getIndex(Vertex v){
  218. if(vertex2index.containsKey(v)) return vertex2index.get(v);
  219. int index=vertex2index.size();
  220. if(index>=index2vertex.length)throw new RuntimeException("Too many vertices in graph");
  221. vertex2index.put(v,index);
  222. index2vertex[index]=v;
  223. return index;
  224. }
  225. /// foo
  226. public void insertEdge(Vertex v1,Vertex v2,int w){
  227. matrix[getIndex(v1)][getIndex(v2)] = w;
  228. }
  229. /// foo
  230. public Collection<Edge> edges(){
  231. HashSet<Edge> edges=new HashSet<>();
  232. for(int i=0;i<numVertex;i++){
  233. for(int j=0;j<numVertex;j++){
  234. Integer weight=matrix[i][j]; // may be null
  235. if(weight==null)continue;
  236. edges.add(new Edge(index2vertex[i],index2vertex[j],weight));
  237. }
  238. }
  239. return edges;
  240. }
  241. /// foo
  242. public Collection<Edge> outEdge(Vertex v1){
  243. HashSet<Edge> edges=new HashSet<>();
  244. int i=vertex2index.get(v1);
  245. for(int j=0;j<numVertex;j++){
  246. Integer weight=matrix[i][j]; // may be null
  247. if(weight==null)continue;
  248. edges.add(new Edge(v1,index2vertex[j],weight));
  249. }
  250. return edges;
  251. }
  252. /// foo
  253. public Integer getWeight(Vertex v1,Vertex v2){
  254. // constant time operation
  255. return matrix[vertex2index.get(v1)][vertex2index.get(v2)];}
  256. }