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