Advertisement
Guest User

lab5_part2

a guest
Mar 31st, 2020
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.85 KB | None | 0 0
  1. import javax.swing.*;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.lang.reflect.Array;
  5. import java.security.InvalidParameterException;
  6. import java.util.*;
  7.  
  8. import static java.lang.System.exit;
  9.  
  10. public class Main {
  11.  
  12.     public static void main(String[] args) {
  13.  
  14.         try {
  15.             Scanner scanner = new Scanner(new File("./src/input.txt"));
  16.  
  17.             Integer n = scanner.nextInt();
  18.             Integer m = scanner.nextInt();
  19.  
  20.             ArrayList<ArrayList<Pair<Integer>>> list = new ArrayList<>();
  21.             for (Integer i = 0; i < n + 1; i++) {
  22.                 list.add(new ArrayList<>());
  23.             }
  24.  
  25.             for (Integer i = 0; i < m; i++) {
  26.                 Integer first = scanner.nextInt();
  27.                 Integer second = scanner.nextInt();
  28.                 Integer weight = scanner.nextInt();
  29.                 list.get(first).add(new Pair<Integer>(second, weight));
  30.             }
  31.  
  32.             Graph graph = new Graph(list);
  33.  
  34.             while (true) {
  35.                 System.out.println(" 1 - Bellman from ONE to ALL \n 2 - Bellman FROM => TO \n 3 - Johnson from ONE to ALL \n 4 - Johnson FROM => TO \n 5 - terminate");
  36.  
  37.                 Scanner consoleScanner = new Scanner(System.in);
  38.  
  39.                 Integer input = consoleScanner.nextInt();
  40.  
  41.                 switch (input) {
  42.                     case 1: {
  43.                         System.out.println("Bellman from ONE to ALL");
  44.                         Integer v = consoleScanner.nextInt();
  45.  
  46.                         graph.bellman(v);
  47.                         break;
  48.                     }
  49.                     case 2: {
  50.                         System.out.println("Bellman FROM => TO");
  51.                         Integer from = consoleScanner.nextInt();
  52.                         Integer to = consoleScanner.nextInt();
  53.  
  54.                         graph.bellman2(from, to);
  55.                         break;
  56.                     }
  57.                     case 3: {
  58.                         System.out.println("Johnson from ONE to ALL");
  59.                         Integer from = consoleScanner.nextInt();
  60.  
  61.                         graph.johnson(from, -1);
  62.                         break;
  63.                     }
  64.                     case 4: {
  65.                         System.out.println("Johnson FROM=>TO");
  66.                         Integer from = consoleScanner.nextInt();
  67.                         Integer to = consoleScanner.nextInt();
  68.  
  69.                         graph.johnson(from, to);
  70.                         break;
  71.                     }
  72.                     case 5: {
  73.                         exit(0);
  74.                     }
  75.  
  76.                 }
  77.             }
  78.  
  79.         } catch (FileNotFoundException ex) {
  80.             ex.printStackTrace();
  81.         };
  82.     }
  83. }
  84.  
  85. class Edge {
  86.  
  87.     public Integer from;
  88.     public Integer to;
  89.     public Integer weight;
  90.  
  91.     Edge(Integer from, Integer to, Integer weight) {
  92.         this.from = from;
  93.         this.to = to;
  94.         this.weight = weight;
  95.     }
  96.  
  97.     @Override
  98.     public String toString() {
  99.         return from + "=>" + to + " " + weight;
  100.     }
  101. }
  102.  
  103. class Graph {
  104.  
  105.     private ArrayList<ArrayList<Pair<Integer> > > graph;
  106.     private ArrayList<Boolean> used;
  107.     private ArrayList<Edge> edges = new ArrayList<>();
  108.  
  109.     Graph(ArrayList<ArrayList<Pair<Integer> > > graph) {
  110.         for (ArrayList<Pair<Integer>> list : graph) {
  111.             list.sort(new Comparator<Pair<Integer>>() {
  112.                 @Override
  113.                 public int compare(Pair<Integer> int1, Pair<Integer> int2) {
  114.                     if (int1.equals(int2)) {
  115.                         return 0;
  116.                     } else if (int1.first < int2.second) {
  117.                         return -1;
  118.                     } else {
  119.                         return 1;
  120.                     }
  121.                 }
  122.             });
  123.         }
  124.  
  125.         for (int i = 0; i < graph.size(); i++) {
  126.             for (int j = 0; j < graph.get(i).size(); j++) {
  127.                 edges.add(new Edge(i, graph.get(i).get(j).first, graph.get(i).get(j).second));
  128.             }
  129.         }
  130.  
  131.         this.graph = graph;
  132.     }
  133.  
  134.     /**
  135.      * Bellman, from ONE to ALL
  136.      * @param v
  137.      */
  138.     public void bellman(Integer v) {
  139.         Integer INF = 1000000000 + 7;
  140.         ArrayList<ArrayList<Integer> > dist = new ArrayList<>();
  141.         for (int i = 0; i < graph.size(); i++) {
  142.             ArrayList<Integer> list = new ArrayList<>(Collections.nCopies(graph.size(), INF));
  143.             dist.add(list);
  144.         }
  145.         dist.get(0).set(v, 0);
  146.         for (int i = 1; i < graph.size(); i++) {
  147.             for (int j = 1; j < graph.size(); j++) {
  148.                 dist.get(i).set(j, dist.get(i-1).get(j));
  149.                 for (Edge e : edges) {
  150.                     if (dist.get(i).get(e.to) > dist.get(i-1).get(e.from) + e.weight) {
  151.                         dist.get(i).set(e.to, dist.get(i-1).get(e.from) + e.weight);
  152.                     }
  153.                 }
  154.             }
  155.         }
  156.  
  157.         for (Edge e : edges) {
  158.             if (dist.get(graph.size() - 1).get(e.to) > dist.get(graph.size() - 1).get(e.from) + e.weight)
  159.                 throw new InvalidParameterException("Cycle with negative weight found!");
  160.         }
  161.  
  162.         for (int i=1; i<dist.size(); i++) {
  163.             if (dist.get(graph.size() - 2).get(i) >= INF )
  164.                 System.out.println("Vertex: " + i + " distance: " + "unreachable");
  165.             else
  166.                 System.out.println("Vertex: " + i + " distance: " + dist.get(graph.size() - 2).get(i));
  167.         }
  168.     }
  169.  
  170.     /**
  171.      * Bellman, FROM => TO
  172.      * @param from
  173.      * @param to
  174.      */
  175.     public void bellman2(Integer from, Integer to) {
  176.         Integer INF = 1000000000 + 7;
  177.         ArrayList<ArrayList<Integer> > dist = new ArrayList<>();
  178.         ArrayList<Integer> history = new ArrayList<>(Collections.nCopies(graph.size(), 0));
  179.         for (int i = 0; i < graph.size(); i++) {
  180.             ArrayList<Integer> list = new ArrayList<>(Collections.nCopies(graph.size(), INF));
  181.             dist.add(list);
  182.         }
  183.         dist.get(0).set(from, 0);
  184.         for (int i = 1; i < graph.size(); i++) {
  185.             for (int j = 1; j < graph.size(); j++) {
  186.                 dist.get(i).set(j, dist.get(i-1).get(j));
  187.                 for (Edge e : edges) {
  188.                     if (dist.get(i).get(e.to) > dist.get(i-1).get(e.from) + e.weight) {
  189.                         dist.get(i).set(e.to, dist.get(i-1).get(e.from) + e.weight);
  190.                         history.set(e.to, e.from);
  191.                     }
  192.                 }
  193.             }
  194.         }
  195.  
  196.         for (Edge e : edges) {
  197.             if (dist.get(graph.size() - 1).get(e.to) > dist.get(graph.size() - 1).get(e.from) + e.weight)
  198.                 throw new InvalidParameterException("Cycle with negative weight found!");
  199.         }
  200.  
  201.         ArrayList<Integer> way = new ArrayList<>();
  202.         for (Integer i = to; i != from; i = history.get(i)) {
  203.             way.add(i);
  204.         }
  205.         way.add(from);
  206.  
  207.         System.out.println("Way " + from + " => " + to);
  208.         for (Integer i = way.size() - 1; i >= 0; i--) {
  209.             if (i != 0)
  210.                 System.out.print(way.get(i) + "=>");
  211.             else
  212.                 System.out.print(way.get(i));
  213.         }
  214.         System.out.println();
  215.     }
  216.  
  217.     public void johnson(Integer from, Integer to) {
  218.         /**
  219.          * Create G' graph(add S)
  220.          */
  221.         ArrayList<ArrayList<Pair<Integer> > > graph1 = new ArrayList<>();
  222.         ArrayList<Edge> edges1 = new ArrayList<>();
  223.         for (int i=0; i<graph.size(); i++) {
  224.             ArrayList<Pair<Integer>> list = new ArrayList<>();
  225.             for (int j=0; j<graph.get(i).size(); j++) {
  226.                 list.add(graph.get(i).get(j));
  227.             }
  228.             graph1.add(list);
  229.         }
  230.         for (Integer i = 0; i < edges.size(); i++) {
  231.             Edge e = edges.get(i);
  232.             edges1.add(new Edge(e.from, e.to, e.weight));
  233.         }
  234.  
  235.         for (int i=0; i<graph1.size(); i++) {
  236.             graph1.get(i).add(new Pair<Integer>(graph1.size(), 0));
  237.         }
  238.  
  239.         ArrayList<Pair<Integer>> list = new ArrayList<>();
  240.  
  241.         for (int i=0; i<graph1.size(); i++) {
  242.             list.add(new Pair<>(i, 0));
  243.             edges1.add(new Edge(graph1.size(), i, 0));
  244.         }
  245.  
  246.         graph1.add(list);
  247.  
  248.         Integer s = graph1.size() - 1;
  249.  
  250.         /**
  251.          * Bellman
  252.          */
  253.         Integer INF = 1000000000 + 7;
  254.         ArrayList<ArrayList<Integer> > dist = new ArrayList<>();
  255.         for (int i = 0; i < graph1.size(); i++) {
  256.             ArrayList<Integer> list1 = new ArrayList<>(Collections.nCopies(graph1.size(), INF));
  257.             dist.add(list1);
  258.         }
  259.         dist.get(0).set(s, 0);
  260.         for (int i = 1; i < graph1.size(); i++) {
  261.             for (int j = 1; j < graph1.size(); j++) {
  262.                 dist.get(i).set(j, dist.get(i-1).get(j));
  263.                 for (Edge e : edges1) {
  264.                     if (dist.get(i).get(e.to) > dist.get(i-1).get(e.from) + e.weight) {
  265.                         dist.get(i).set(e.to, dist.get(i-1).get(e.from) + e.weight);
  266.                     }
  267.                 }
  268.             }
  269.         }
  270.  
  271.         for (Edge e : edges1) {
  272.             if (dist.get(graph1.size() - 1).get(e.to) > dist.get(graph1.size() - 1).get(e.from) + e.weight)
  273.                 throw new InvalidParameterException("Cycle with negative weight found!");
  274.         }
  275.  
  276.         /**
  277.          * Determine h(v)
  278.          */
  279.         ArrayList<Integer> h = new ArrayList<>(Collections.nCopies(graph1.size(), 0));
  280.         for (int i=0; i<dist.size(); i++) {
  281.             h.set(i, dist.get(graph1.size() - 2).get(i));
  282.         }
  283.  
  284.         /**
  285.          * Determine new weights w'(u, v) = w(u, v) + h(u) - h(v)
  286.          */
  287.         for (Edge e : edges1) {
  288.             e.weight = e.weight + h.get(e.from) - h.get(e.to);
  289.         }
  290.  
  291.         for (Integer i=0; i<graph1.size(); i++) {
  292.             for (Integer j=0; j<graph1.get(i).size(); j++) {
  293.                 for (Edge e : edges1) {
  294.                     if (e.from == i && e.to == graph1.get(i).get(j).first) {
  295.                         graph1.get(i).get(j).second = e.weight;
  296.                     }
  297.                 }
  298.             }
  299.         }
  300.  
  301.         /**
  302.          * Dijkstra
  303.          */
  304.         ArrayList<ArrayList<Integer> > D = new ArrayList<>();
  305.         ArrayList<ArrayList<Integer> > historyD = new ArrayList<>();
  306.         D.add(new ArrayList<>(Collections.nCopies(graph1.size(), INF)));
  307.         historyD.add(new ArrayList<>(Collections.nCopies(graph1.size(), INF)));
  308.         for (Integer u = 1; u < graph1.size() - 1; u++) {
  309.             ArrayList<Integer> _dist = new ArrayList<>(Collections.nCopies(graph1.size(), INF));
  310.             _dist.set(u, 0);
  311.             TreeSet<Pair<Integer>> st = new TreeSet<Pair<Integer>>();
  312.             st.add(new Pair<Integer>(_dist.get(u), u));
  313.             ArrayList<Integer> history = new ArrayList<>(Collections.nCopies(graph1.size(), INF));
  314.             while (!st.isEmpty()) {
  315.                 Integer v = st.first().second;
  316.                 st.remove(st.first());
  317.                 if (v == graph1.size()-1)
  318.                     continue;
  319.  
  320.                 for (Pair<Integer> _to : graph1.get(v)) {
  321.                     Integer __to = _to.first;
  322.                     Integer len = _to.second;
  323.                     if (__to == s)
  324.                         continue;
  325.  
  326.                     if (_dist.get(v) + len < _dist.get(__to)) {
  327.                         st.remove(new Pair<Integer>(_dist.get(__to), __to));
  328.                         _dist.set(__to, _dist.get(v) + len);
  329.                         if (_dist.get(v) + len < 0) {
  330.                             throw new IllegalArgumentException("Edge cannot have weight less than 0");
  331.                         }
  332.                         history.set(__to, v);
  333.                         st.add(new Pair<Integer>(_dist.get(__to), __to));
  334.                     }
  335.                 }
  336.             }
  337.  
  338.             D.add(_dist);
  339.             historyD.add(history);
  340.         }
  341.  
  342.         /**
  343.          * new distances d(u, v) = d'(u, v) - h(u) + h(v)
  344.          */
  345.         ArrayList<ArrayList<Integer> > newD = new ArrayList<ArrayList<Integer>>();
  346.         for (int i=0; i<graph1.size(); i++) {
  347.             ArrayList<Integer> list2 = new ArrayList<>(Collections.nCopies(graph1.size(), 0));
  348.             newD.add(list2);
  349.         }
  350.         for (int i=1; i<graph1.size()-1; i++) {
  351.             for (int j=1; j<graph1.size()-1; j++) {
  352.                 newD.get(i).set(j, D.get(i).get(j) - h.get(i) + h.get(j));
  353.             }
  354.         }
  355.  
  356.         if (to == -1) {
  357.             for (int i=1; i<graph1.size()-1; i++) {
  358.                 System.out.println("Vertex " + i + " length: " + newD.get(from).get(i));
  359.             }
  360.         } else {
  361.             ArrayList<Integer> way = new ArrayList<>();
  362.             for (Integer i = to; i != from; i = historyD.get(from).get(i)) {
  363.                 way.add(i);
  364.                 if (historyD.get(from).get(i) == INF)
  365.                     break;
  366.             }
  367.             way.add(from);
  368.  
  369.             System.out.println("Length: " + newD.get(from).get(to));
  370.             for (Integer i = way.size() - 1; i >= 0; i--) {
  371.                 System.out.print(way.get(i));
  372.                 if (i != 0)
  373.                     System.out.print("=>");
  374.             }
  375.             System.out.println();
  376.         }
  377.     }
  378. }
  379.  
  380. class Pair<T extends Comparable<T>> implements Comparable<Pair<T>> {
  381.     public T first;
  382.     public T second;
  383.  
  384.     Pair(T first, T second) {
  385.         this.first = first;
  386.         this.second = second;
  387.     }
  388.  
  389.     @Override
  390.     public int compareTo(Pair<T> pair) {
  391.         if (this.first == pair.first) {
  392.             return this.second.compareTo(pair.second);
  393.         } else {
  394.             return this.first.compareTo(pair.first);
  395.         }
  396.     }
  397.  
  398.     @Override
  399.     public String toString() {
  400.         return first + "-" + second;
  401.     }
  402. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement