Advertisement
NHristovski

FordFulkerson

Apr 17th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.83 KB | None | 0 0
  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.Comparator;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.Hashtable;
  7. import java.util.LinkedList;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Objects;
  11. import java.util.PriorityQueue;
  12. import java.util.Queue;
  13. import java.util.Scanner;
  14. import java.util.Set;
  15. import java.util.stream.Collectors;
  16. import jdk.management.resource.ResourceType;
  17.  
  18.  
  19.  
  20. class FordFulkerson<E extends Comparable<E>>{
  21.  
  22. class BFS_FF<E extends Comparable<E>>{
  23.  
  24. public void run(Graph<E> g,E startingNode,boolean resetVisited){
  25. Hashtable<Vertex<E>, List<Edge<E>>> table = g.getHashtableOutEdges();
  26.  
  27. if (resetVisited){
  28. for(Vertex<E> vertex : g.getVertices()){
  29. vertex.setVisited(false);
  30. }
  31. }
  32.  
  33. for(Vertex<E> vertex : g.getVertices()){
  34. vertex.setMinDistance(Double.MAX_VALUE);
  35. }
  36.  
  37. Vertex<E> node = g.getVertex(startingNode);
  38. node.setMinDistance(0);
  39. node.setVisited(true);
  40. node.setMaxFlow(Double.MAX_VALUE);
  41. Queue<Vertex<E>> q = new LinkedList<>();
  42. q.offer(node);
  43.  
  44. while(!q.isEmpty()){
  45. Vertex<E> currentNode = q.poll();
  46.  
  47. List<Vertex<E>> adjNodes = new ArrayList<>();
  48. for (Edge<E> edge : table.get(currentNode)){
  49. if (edge.getTransferable() > 0d){
  50. adjNodes.add(edge.getDestination());
  51. }
  52. }
  53.  
  54. for (Vertex<E> ver : adjNodes){
  55. if (!ver.isVisited()){
  56. ver.setPredecessor(currentNode);
  57. ver.setMinDistance(currentNode.getMinDistance() + 1);
  58. ver.setVisited(true);
  59. ver.setMaxFlow(Math.min(currentNode.getMaxFlow(), g.getEdgeBetween(currentNode.getData(), ver.getData()).getTransferable()));
  60. q.offer(ver);
  61. }
  62. }
  63. }
  64. }
  65. }
  66. public double run(Graph<E> graph,Vertex<E> startingNode,Vertex<E> endNode){
  67. BFS_FF bfs = new BFS_FF();
  68. double result = 0d;
  69. while (true){
  70. bfs.run(graph, startingNode.getData(),true);
  71. if (endNode.getMinDistance() == Double.MAX_VALUE){
  72. return result;
  73. }
  74. double maxFlow = endNode.getMaxFlow();
  75. List<Vertex<E>> vertices = new ArrayList<>();
  76. Vertex<E> temp = endNode;
  77. //System.out.println("Predecessors");
  78. while(temp.hasPredecessor()){
  79. //System.out.println(temp);
  80. vertices.add(temp);
  81. temp = temp.getPredecessor();
  82. }
  83. vertices.add(temp);
  84.  
  85. Collections.reverse(vertices);
  86.  
  87. for (int i = 0; i < vertices.size() - 1; i++){
  88. Edge<E> edge = graph.getEdgeBetween(vertices.get(i), vertices.get(i + 1));
  89. edge.decreaseTransferable(maxFlow);
  90. }
  91. //System.out.println("Patot e " + vertices);
  92. //System.out.println("maxFlow " + maxFlow);
  93. result += maxFlow;
  94. }
  95. }
  96. }
  97.  
  98. class DFS<E extends Comparable<E>>{
  99. int time;
  100. public DFS(){
  101. time = 0;
  102. }
  103.  
  104. private void visit(Vertex<E> u,Hashtable<Vertex<E>,List<Edge<E > > > table){
  105. u.setColor(Color.GRAY);
  106. time++;
  107. u.setTimeVisited(time);
  108.  
  109. Set<Vertex<E>> adjVertices = new HashSet<>();
  110. List<Edge<E>> adj = table.get(u);
  111. for (Edge<E> edge : adj){
  112. adjVertices.add(edge.getDestination());
  113. }
  114.  
  115. for (Vertex<E> ver : adjVertices){
  116. if (ver.getColor() == Color.WHITE){
  117. ver.setPredecessor(u);
  118. ver.setMinDistance(u.getMinDistance() + 1);
  119. visit(ver,table);
  120. }
  121. }
  122. u.setColor(Color.BLACK);
  123. time++;
  124. u.setTimeFinished(time);
  125. }
  126. public void run(Graph<E> g){
  127. this.time = 0;
  128. Hashtable<Vertex<E>,List<Edge<E>>> table = g.getHashtableOutEdges();
  129.  
  130. List<Vertex<E>> vertices = new ArrayList<>();
  131. vertices = g.getVertices();
  132.  
  133. for(Vertex<E> vertex : vertices){
  134. vertex.setColor(Color.WHITE);
  135. vertex.setMinDistance(0d);
  136. vertex.setPredecessor(null);
  137. }
  138.  
  139. for (Vertex<E> vertex : vertices){
  140. if (vertex.getColor() == Color.WHITE){
  141. visit(vertex,table);
  142. }
  143. }
  144. }
  145. }
  146.  
  147. class BFS<E extends Comparable<E>>{
  148.  
  149. public void run(Graph<E> g,E startingNode,boolean resetVisited){
  150. Hashtable<Vertex<E>, List<Edge<E>>> table = g.getHashtableOutEdges();
  151.  
  152. if (resetVisited){
  153. for(Vertex<E> vertex : g.getVertices()){
  154. vertex.setVisited(false);
  155. }
  156. }
  157.  
  158. for(Vertex<E> vertex : g.getVertices()){
  159. vertex.setMinDistance(Double.MAX_VALUE);
  160. }
  161.  
  162. Vertex<E> node = g.getVertex(startingNode);
  163. node.setMinDistance(0);
  164. node.setVisited(true);
  165. Queue<Vertex<E>> q = new LinkedList<>();
  166. q.offer(node);
  167.  
  168. while(!q.isEmpty()){
  169. Vertex<E> currentNode = q.poll();
  170.  
  171. List<Vertex<E>> adjNodes = new ArrayList<>();
  172. for (Edge<E> edge : table.get(currentNode)){
  173. adjNodes.add(edge.getDestination());
  174. }
  175.  
  176. for (Vertex<E> ver : adjNodes){
  177. if (!ver.isVisited()){
  178. ver.setPredecessor(currentNode);
  179. ver.setMinDistance(currentNode.getMinDistance() + 1);
  180. ver.setVisited(true);
  181. q.offer(ver);
  182. }
  183. }
  184. }
  185. }
  186.  
  187.  
  188. }
  189.  
  190. enum Color{
  191. UNDEFINED,
  192. WHITE,
  193. GRAY,
  194. BLACK
  195. }
  196. class Vertex<E extends Comparable<E>> implements Comparable<Vertex<E>>{
  197. private E data;
  198. private double minDistance;
  199. private Vertex predecessor;
  200. private Color color;
  201. private Integer timeVisited;
  202. private Integer timeFinished;
  203. boolean visited;
  204. double maxFlow;
  205.  
  206. public double getMaxFlow() {
  207. return maxFlow;
  208. }
  209.  
  210. public void setMaxFlow(double maxFlow) {
  211. this.maxFlow = maxFlow;
  212. }
  213.  
  214. public boolean isVisited() {
  215. return visited;
  216. }
  217.  
  218. public void setVisited(boolean visited) {
  219. this.visited = visited;
  220. }
  221.  
  222. public Vertex(E data){
  223. this.data = data;
  224. this.minDistance = Double.MAX_VALUE;
  225. this.predecessor = null;
  226. color = Color.UNDEFINED;
  227. timeVisited = null;
  228. timeFinished = null;
  229. visited = false;
  230. maxFlow = 0d;
  231. }
  232.  
  233. public Integer getTimeVisited() {
  234. return timeVisited;
  235. }
  236.  
  237. public void setTimeVisited(Integer timeVisited) {
  238. this.timeVisited = timeVisited;
  239. }
  240.  
  241. public Integer getTimeFinished() {
  242. return timeFinished;
  243. }
  244.  
  245. public void setTimeFinished(Integer timeFinished) {
  246. this.timeFinished = timeFinished;
  247. }
  248.  
  249. public Color getColor() {
  250. return color;
  251. }
  252.  
  253. public void setColor(Color color) {
  254. this.color = color;
  255. }
  256.  
  257. public boolean hasPredecessor(){
  258. return this.predecessor != null;
  259. }
  260.  
  261. public double getMinDistance() {
  262. return minDistance;
  263. }
  264.  
  265. public void setMinDistance(double minDistance) {
  266. this.minDistance = minDistance;
  267. }
  268.  
  269. public Vertex<E> getPredecessor() {
  270. return predecessor;
  271. }
  272.  
  273. public void setPredecessor(Vertex predecessor) {
  274. this.predecessor = predecessor;
  275. }
  276.  
  277. public E getData() {
  278. return data;
  279. }
  280.  
  281. public void setData(E data) {
  282. this.data = data;
  283. }
  284.  
  285. @Override
  286. public int compareTo(Vertex<E> v) {
  287. return Double.compare(minDistance, v.getMinDistance());
  288. }
  289.  
  290. @Override
  291. public int hashCode() {
  292. int hash = 3;
  293. hash = 29 * hash + Objects.hashCode(this.data);
  294. return hash;
  295. }
  296.  
  297. @Override
  298. public boolean equals(Object obj) {
  299. if (this == obj) {
  300. return true;
  301. }
  302. if (obj == null) {
  303. return false;
  304. }
  305. if (getClass() != obj.getClass()) {
  306. return false;
  307. }
  308. final Vertex<E> other = (Vertex<E>) obj;
  309. if (!this.data.equals(other.data)) {
  310. return false;
  311. }
  312. return true;
  313. }
  314.  
  315. @Override
  316. public String toString(){
  317. return "Vertex " + this.getData();
  318. }
  319.  
  320. public String toStringMoreInfo(){
  321. StringBuilder sb = new StringBuilder();
  322. sb.append("Vertex with data: ")
  323. .append(this.data)
  324. .append(" minDist: ");
  325. if (this.minDistance == Double.MAX_VALUE || this.minDistance == Double.MAX_VALUE / 2){
  326. sb.append("INF");
  327. }else{
  328. sb.append(this.minDistance);
  329. }
  330.  
  331. sb.append("\tvisited: " + timeVisited + " - left: " + timeFinished);
  332. sb.append(" COLOR: " + this.color);
  333. return sb.toString();
  334. }
  335.  
  336. }
  337.  
  338. class Edge<E extends Comparable<E>> implements Comparable<Edge<E>>{
  339. private Vertex<E> source;
  340. private Vertex<E> destination;
  341. private double weight;
  342. private double transferable;
  343.  
  344.  
  345. public Edge(Vertex<E> source, Vertex<E> destination, double weight) {
  346. this.source = source;
  347. this.destination = destination;
  348. this.weight = weight;
  349. this.transferable = weight;
  350. }
  351.  
  352. public double getTransferable() {
  353. return transferable;
  354. }
  355.  
  356. public void setTransferable(double transferable) {
  357. this.transferable = transferable;
  358. }
  359.  
  360. public void decreaseTransferable(double amount){
  361. this.transferable -= amount;
  362. }
  363.  
  364. public Vertex<E> getSource() {
  365. return source;
  366. }
  367.  
  368. public void setSource(Vertex<E> source) {
  369. this.source = source;
  370. }
  371.  
  372. public Vertex<E> getDestination() {
  373. return destination;
  374. }
  375.  
  376. public void setDestination(Vertex<E> destination) {
  377. this.destination = destination;
  378. }
  379.  
  380. public double getWeight() {
  381. return weight;
  382. }
  383.  
  384. public void setWeight(double weight) {
  385. this.weight = weight;
  386. }
  387.  
  388. public void changeDirection(){
  389. Vertex<E> source = this.getSource();
  390. Vertex<E> destination = this.getDestination();
  391.  
  392. this.setDestination(source);
  393. this.setSource(destination);
  394. }
  395. @Override
  396. public String toString(){
  397. StringBuilder sb = new StringBuilder();
  398. sb.append("Edge from: ")
  399. .append(this.source.getData())
  400. .append("\tto: ")
  401. .append(this.destination.getData())
  402. .append("\twith weight: " + this.weight);
  403. return sb.toString();
  404. }
  405.  
  406. @Override
  407. public int compareTo(Edge<E> edge) {
  408. return Double.compare(this.weight, edge.weight);
  409. }
  410.  
  411. @Override
  412. public int hashCode() {
  413. int hash = 7;
  414. hash = 97 * hash + Objects.hashCode(this.source);
  415. hash = 97 * hash + Objects.hashCode(this.destination);
  416. hash = 97 * hash + (int) (Double.doubleToLongBits(this.weight) ^ (Double.doubleToLongBits(this.weight) >>> 32));
  417. return hash;
  418. }
  419.  
  420. @Override
  421. public boolean equals(Object obj) {
  422. if (this == obj) {
  423. return true;
  424. }
  425. if (obj == null) {
  426. return false;
  427. }
  428. if (getClass() != obj.getClass()) {
  429. return false;
  430. }
  431. final Edge<?> other = (Edge<?>) obj;
  432.  
  433. if (!Objects.equals(this.source, other.source)) {
  434. return false;
  435. }
  436. if (!Objects.equals(this.destination, other.destination)) {
  437. return false;
  438. }
  439. return true;
  440. }
  441.  
  442.  
  443.  
  444.  
  445. }
  446.  
  447. class Graph<E extends Comparable<E>>{
  448.  
  449. List<Vertex<E>> vertices;
  450. List<Edge<E>> edges;
  451. Map<E,Integer> indexes; // E( name of the vertex) -> Integer (position in list vertices)
  452. Map<String,Edge<E>> hashedEdges;
  453.  
  454. public Graph(){
  455. vertices = new ArrayList<>();
  456. edges = new ArrayList<>();
  457. indexes = new HashMap<>();
  458. hashedEdges = new HashMap<>();
  459. }
  460.  
  461. public void addVertex(E data){
  462. Vertex<E> vertex = new Vertex<>(data);
  463. vertices.add(vertex);
  464. int index = vertices.size() - 1;
  465. indexes.put(data, index);
  466. }
  467. public boolean removeVertex(E data){
  468. Vertex<E> v = new Vertex<>(data);
  469. if (vertices.contains(v)){
  470. Vertex<E> vertexToRemove = this.getVertex(data);
  471. vertices.remove(vertexToRemove);
  472. for (int i = 0; i < this.edges.size(); i++){
  473. if (edges.get(i).getSource().equals(vertexToRemove) || edges.get(i).getDestination().equals(vertexToRemove)){
  474. this.edges.remove(edges.get(i));
  475. i--;
  476. }
  477. }
  478. return true;
  479. }
  480. return false;
  481. }
  482.  
  483. public Vertex<E> getVertex(E data){
  484. return vertices.get(indexes.get(data));
  485. }
  486.  
  487. private boolean addEdge(Vertex<E> source,Vertex<E> destination,double weight){
  488. Edge<E> edge = new Edge<E>(source,destination,weight);
  489. hashedEdges.put(source.getData() + "-" + destination.getData(),edge);
  490. return edges.add(edge);
  491. }
  492.  
  493. public boolean removeDirectedEdge(Edge<E> edge){
  494. return edges.remove(edge);
  495. }
  496. public boolean removeUndirectedEdge(Edge<E> edge){
  497. Edge<E> secondEdge = new Edge<>(edge.getDestination(),edge.getSource(),edge.getWeight());
  498. return edges.remove(edge) && edges.remove(secondEdge);
  499. }
  500.  
  501. public boolean addDirectedEdge(E source,E destination,double weight){
  502. Vertex<E> s = vertices.get(indexes.get(source));
  503. Vertex<E> d = vertices.get(indexes.get(destination));
  504. return addEdge(s,d,weight);
  505. }
  506. public boolean addUndirectedEdge(E source,E destination,double weight){
  507. Vertex<E> s = vertices.get(indexes.get(source));
  508. Vertex<E> d = vertices.get(indexes.get(destination));
  509.  
  510. return addEdge(s,d,weight) && addEdge(d,s,weight);
  511. }
  512.  
  513. public List<Vertex<E>> getVertices(){
  514. return this.vertices;
  515. }
  516.  
  517. public List<Edge<E>> getEdges(){
  518. return this.edges;
  519. }
  520.  
  521. public Edge<E> getEdgeBetween(E source,E destination){
  522. return hashedEdges.get(source + "-" + destination);
  523. }
  524. public Edge<E> getEdgeBetween(Vertex<E> source,Vertex<E> destination){
  525. return getEdgeBetween(source.getData(),destination.getData());
  526. }
  527.  
  528. @Override
  529. public String toString(){
  530. StringBuilder sb = new StringBuilder();
  531. sb.append("Vertices:\n");
  532. for (Vertex<E> v : this.getVertices()){
  533. sb.append(v.toString() + "\n");
  534. }
  535.  
  536. sb.append("\n").append("Edges:\n");
  537. for (Edge<E> e : this.getEdges()){
  538. sb.append(e.toString()).append("\n");
  539. }
  540.  
  541. return sb.toString();
  542. }
  543.  
  544.  
  545. /**
  546. * Hashtable of Node and list of Edges that start from Node
  547. *
  548. * @return Hashtable
  549. */
  550. public Hashtable<Vertex<E>, List<Edge<E> > > getHashtableOutEdges(){
  551. Hashtable<Vertex<E>, List<Edge<E> > > table = new Hashtable<>();
  552. List<Edge<E>> lst;
  553. for (Vertex<E> v : this.vertices){
  554. lst = new LinkedList<>();
  555. table.put(v,lst);
  556. }
  557.  
  558. for (Edge<E> e : this.edges){
  559. table.get(e.getSource()).add(e);
  560. }
  561.  
  562. return table;
  563. }
  564.  
  565. /**
  566. *
  567. * Hashtable of Node and list of Edges that go in Node
  568. *
  569. * @return Hashtable<Node,Edges that go in Node>
  570. */
  571.  
  572. public Hashtable<Vertex<E>, List<Edge<E> > > getHashtableInEdges(){
  573. Hashtable<Vertex<E>, List<Edge<E> > > table = new Hashtable<>();
  574. List<Edge<E>> lst;
  575. for (Vertex<E> v : this.vertices){
  576. lst = new LinkedList<>();
  577. table.put(v,lst);
  578. }
  579.  
  580. for (Edge<E> e : this.edges){
  581. table.get(e.getDestination()).add(e);
  582. }
  583.  
  584. return table;
  585. }
  586.  
  587. public double[][] getAdjMatrix(){
  588. int N = vertices.size();
  589. double[][] matrix = new double[N][N];
  590. for (int i = 0; i < N; i++){
  591. for (int j = 0; j < N; j++){
  592. matrix[i][j] = Double.MAX_VALUE;
  593. }
  594. }
  595. List<Edge<E>> egdes = this.getEdges();
  596. for (Edge<E> e : edges){
  597. matrix[indexes.get(e.getSource().getData())][indexes.get(e.getDestination().getData())] = e.getWeight();
  598. }
  599. return matrix;
  600. }
  601.  
  602. }
  603.  
  604. public class Main{
  605.  
  606. public static void main(String[] args){
  607. Graph<String> g = new Graph<>();
  608.  
  609. g.addVertex("S");
  610. g.addVertex("A");
  611. g.addVertex("B");
  612. g.addVertex("T");
  613.  
  614. g.addDirectedEdge("S", "A", 2);
  615. g.addDirectedEdge("A", "T", 4);
  616. g.addDirectedEdge("A", "B", 1);
  617. g.addDirectedEdge("S", "B", 5);
  618. g.addDirectedEdge("B", "T", 3);
  619.  
  620.  
  621. FordFulkerson<String> fordFulkerson = new FordFulkerson<>();
  622. System.out.println(fordFulkerson.run(g, g.getVertex("S"), g.getVertex("T")));
  623.  
  624.  
  625. }
  626. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement