Filip_Markoski

[ADSx] - Fixed Graph Codes

Jan 28th, 2018
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.00 KB | None | 0 0
  1. import java.util.*;
  2. import java.util.stream.Collectors;
  3. import java.util.stream.IntStream;
  4.  
  5. public class Board {
  6.  
  7.     public static void main(String args[]) {
  8.         String text = "100 100\n" +
  9.                 "2 100 50 50";
  10.         //text = "3 3\n" +
  11.         //       "1 1 3 3";
  12.  
  13.         //text = "8 8 \n" +
  14.         //        "1 1 8 8";
  15.         Scanner scanner = new Scanner(text);
  16.         //Scanner scanner = new Scanner(System.in);
  17.         int rows = scanner.nextInt();
  18.         int columns = scanner.nextInt();
  19.         scanner.nextLine();
  20.  
  21.         // Minus one for all because we iterate starting from 0
  22.         int x1 = scanner.nextInt() - 1;
  23.         int y1 = scanner.nextInt() - 1;
  24.         int x2 = scanner.nextInt() - 1;
  25.         int y2 = scanner.nextInt() - 1;
  26.  
  27.         /**
  28.          * https://en.wikipedia.org/wiki/Knight%27s_graph
  29.          * https://www.geeksforgeeks.org/minimum-steps-reach-target-knight/
  30.          * */
  31.  
  32.         Integer elements[] = new Integer[(rows + 1) * (columns + 1)];
  33.         IntStream.range(0, elements.length).forEach(i -> elements[i] = i);
  34.  
  35.         //System.out.print(Arrays.toString(elements));
  36.  
  37.         Graph<Integer> graph = new Graph<>((rows + 1) * (columns + 1), elements);
  38.  
  39.         for (int i = 0; i < rows; i++) {
  40.             for (int j = 0; j < columns; j++) {
  41.                 if (i + 2 < rows && j + 1 < columns) {
  42.                     graph.addEdge(transform(i, j, columns), transform(i + 2, j + 1, columns), 1);
  43.                 }
  44.                 if (i + 2 < rows && j - 1 >= 0) {
  45.                     graph.addEdge(transform(i, j, columns), transform(i + 2, j - 1, columns), 1);
  46.                 }
  47.                 if (i - 2 >= 0 && j + 1 < columns) {
  48.                     graph.addEdge(transform(i, j, columns), transform(i - 2, j + 1, columns), 1);
  49.                 }
  50.                 if (i - 2 >= 0 && j - 1 >= 0) {
  51.                     graph.addEdge(transform(i, j, columns), transform(i - 2, j - 1, columns), 1);
  52.                 }
  53.                 if (j + 2 < columns && i + 1 < rows) {
  54.                     graph.addEdge(transform(i, j, columns), transform(j + 2, i + 1, columns), 1);
  55.                 }
  56.                 if (j + 2 < columns && i - 1 >= 0) {
  57.                     graph.addEdge(transform(i, j, columns), transform(j + 2, i - 1, columns), 1);
  58.                 }
  59.                 if (j - 2 >= 0 && i + 1 < rows) {
  60.                     graph.addEdge(transform(i, j, columns), transform(j - 2, i + 1, columns), 1);
  61.                 }
  62.                 if (j - 2 >= 0 && i - 1 >= 0) {
  63.                     graph.addEdge(transform(i, j, columns), transform(j - 2, i - 1, columns), 1);
  64.                 }
  65.             }
  66.         }
  67.  
  68.         int from = transform(x1, y1, columns);
  69.         int to = transform(x2, y2, columns);
  70.         //int steps = bfsSearch(graph, from, to);
  71.  
  72.         System.out.println(graph.dijkstra(from, to));
  73.  
  74.     }
  75.  
  76.     public static int transform(int i, int j, int n) {
  77.         return i * n + j;
  78.     }
  79. /*
  80.     public static int bfsSearch(Graph<Integer> g, int from, int to) {
  81.         Queue<Integer> nodes = new LinkedList<>();
  82.         Queue<Integer> steps = new LinkedList<>();
  83.         HashSet<Integer> visited = new HashSet<>();
  84.         nodes.add(from);
  85.         steps.add(0);
  86.         while (!nodes.isEmpty()) {
  87.             int c = nodes.poll();
  88.             int st = steps.poll();
  89.             if (visited.contains(c)) {
  90.                 continue;
  91.             }
  92.             visited.add(c);
  93.             if (c == to) {
  94.                 return st;
  95.             }
  96.             GraphNode<Integer> current = g.adjList[c];
  97.             for (GraphNode<Integer> neighbor : current.getNeighbors()) {
  98.                 nodes.add(neighbor.getIndex());
  99.                 steps.add(st + 1);
  100.             }
  101.         }
  102.         return -1;
  103.     }
  104.  
  105.     public static <T> void printMatrix(T matrix[][]) {
  106.         System.out.println("Main.");
  107.         Arrays.stream(matrix)
  108.                 .map(Arrays::toString)
  109.                 .forEach(System.out::println);
  110.     }
  111.  
  112.     public static boolean isInside(int x, int y, int N) {
  113.         if (x >= 1 && x <= N && y >= 1 && y <= N) return true;
  114.         return false;
  115.     }
  116.  
  117.     public static int minStepToReachTarget(int knightPos[], int targetPos[], int N) {
  118.         //  x and y direction, where a knight can move
  119.         int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2};
  120.         int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};
  121.  
  122.         //  queue for storing states of knight in board
  123.         Queue<Cell> queue = new LinkedList<>();
  124.  
  125.         //  push starting position of knight with 0 distance
  126.         queue.add(new Cell(knightPos[0], knightPos[1], 0));
  127.  
  128.         Cell t;
  129.         int x, y;
  130.         boolean visited[][] = new boolean[N + 1][N + 1];
  131.  
  132.         //  make all cell unvisited
  133.         for (int i = 1; i <= N; i++)
  134.             for (int j = 1; j <= N; j++)
  135.                 visited[i][j] = false;
  136.  
  137.         //  visit starting state
  138.         visited[knightPos[0]][knightPos[1]] = true;
  139.  
  140.         //  loop until we have one element in queue
  141.         while (!queue.isEmpty()) {
  142.             t = queue.poll();
  143.             visited[t.x][t.y] = true;
  144.  
  145.             // if current cell is equal to target cell,
  146.             // return its distance
  147.             if (t.x == targetPos[0] && t.y == targetPos[1])
  148.                 return t.dis;
  149.  
  150.             //  loop for all reachable states
  151.             for (int i = 0; i < dx.length; i++) {
  152.                 x = t.x + dx[i];
  153.                 y = t.y + dy[i];
  154.  
  155.                 // If rechable state is not yet visited and
  156.                 // inside board, push that state into queue
  157.                 if (isInside(x, y, N) && !visited[x][y])
  158.                     queue.add(new Cell(x, y, t.dis + 1));
  159.  
  160.             }
  161.         }
  162.         return -1;
  163.     }
  164.  
  165. */
  166. }
  167.  
  168.  
  169. class Edge implements Comparable<Edge> {
  170.     // Private
  171.     private int fromVertex, toVertex;
  172.     private int weight;
  173.  
  174.     // Public
  175.     public Edge(int from, int to, int weight) {
  176.         this.fromVertex = from;
  177.         this.toVertex = to;
  178.         this.weight = weight;
  179.     }
  180.  
  181.     public int getFrom() {
  182.         return this.fromVertex;
  183.     }
  184.  
  185.     public int getTo() {
  186.         return this.toVertex;
  187.     }
  188.  
  189.     public int getWeight() {
  190.         return this.weight;
  191.     }
  192.  
  193.     @Override
  194.     public int compareTo(Edge o) {
  195.         return Integer.compare(weight, o.weight);
  196.     }
  197. }
  198.  
  199. class GraphNode<E> {
  200.     // Private
  201.     private int index;
  202.     private E info;
  203.     private LinkedList<GraphNodeNeighbor<E>> neighbors;
  204.  
  205.     // Public
  206.     public GraphNode(int index, E info) {
  207.         this.index = index;
  208.         this.info = info;
  209.         neighbors = new LinkedList<>();
  210.     }
  211.  
  212.     public boolean containsNeighbor(GraphNode<E> o) {
  213.         return neighbors.contains(new GraphNodeNeighbor<>(o));
  214.     }
  215.  
  216.     public void addNeighbor(GraphNode<E> o, int weight) {
  217.         neighbors.add(new GraphNodeNeighbor<>(o, weight));
  218.     }
  219.  
  220.     public void removeNeighbor(GraphNode<E> o) {
  221.         neighbors.remove(new GraphNodeNeighbor<>(o));
  222.     }
  223.  
  224.     @Override
  225.     public String toString() {
  226.         return neighbors.stream().map(i -> "(" + i.node.index + "," + i.weight + ")").collect(Collectors.joining(" ", "INFO:" + index + " SOSEDI:", ""));
  227.     }
  228.  
  229.     public void updateNeighborWeight(GraphNode<E> o, int weight) {
  230.         for (GraphNodeNeighbor<E> pom : neighbors)
  231.             if (pom.node.equals(o))
  232.                 pom.weight = weight;
  233.     }
  234.  
  235.     @Override
  236.     public boolean equals(Object o) {
  237.         if (this == o)
  238.             return true;
  239.         if (o == null || getClass() != o.getClass())
  240.             return false;
  241.  
  242.         GraphNode<?> graphNode = (GraphNode<?>) o;
  243.  
  244.         return index == graphNode.index;
  245.     }
  246.  
  247.     public int getIndex() {
  248.         return index;
  249.     }
  250.  
  251.     public void setIndex(int index) {
  252.         this.index = index;
  253.     }
  254.  
  255.     public E getInfo() {
  256.         return info;
  257.     }
  258.  
  259.     public void setInfo(E info) {
  260.         this.info = info;
  261.     }
  262.  
  263.     public LinkedList<GraphNodeNeighbor<E>> getNeighbors() {
  264.         return neighbors;
  265.     }
  266.  
  267.     public void setNeighbors(LinkedList<GraphNodeNeighbor<E>> neighbors) {
  268.         this.neighbors = neighbors;
  269.     }
  270. }
  271.  
  272. class GraphNodeNeighbor<E> {
  273.     // Private
  274.     GraphNode<E> node;
  275.     int weight;
  276.  
  277.     // Public
  278.     public GraphNodeNeighbor(GraphNode<E> node, int weight) {
  279.         this.node = node;
  280.         this.weight = weight;
  281.     }
  282.  
  283.     public GraphNodeNeighbor(GraphNode<E> node) {
  284.         this.node = node;
  285.     }
  286.  
  287.     @Override
  288.     public boolean equals(Object o) {
  289.         if (this == o)
  290.             return true;
  291.         if (o == null || getClass() != o.getClass())
  292.             return false;
  293.  
  294.         GraphNodeNeighbor<?> that = (GraphNodeNeighbor<?>) o;
  295.  
  296.         return node != null ? node.equals(that.node) : that.node == null;
  297.     }
  298. }
  299.  
  300. class Graph<E> {
  301.     // Private
  302.     private int nodesCount;
  303.     private GraphNode<E>[] adjacencyList;
  304.  
  305.     // Public
  306.     public Graph(int nodesCount, E[] list) {
  307.         this.nodesCount = nodesCount;
  308.         adjacencyList = (GraphNode<E>[]) new GraphNode[nodesCount];
  309.         for (int i = 0; i < nodesCount; i++)
  310.             adjacencyList[i] = new GraphNode<>(i, list[i]);
  311.     }
  312.  
  313.     public Graph(int nodesCount) {
  314.         this.nodesCount = nodesCount;
  315.         adjacencyList = (GraphNode<E>[]) new GraphNode[nodesCount];
  316.         for (int i = 0; i < nodesCount; i++)
  317.             adjacencyList[i] = new GraphNode<>(i, null);
  318.     }
  319.  
  320.     int adjacent(int node1index, int node2index) {
  321.         return adjacencyList[node1index].containsNeighbor(adjacencyList[node2index]) ? 1 : 0;
  322.     }
  323.  
  324.     void addEdge(int node1index, int node2index, int weight) {
  325.         if (adjacencyList[node1index].containsNeighbor(adjacencyList[node2index]))
  326.             adjacencyList[node1index].updateNeighborWeight(adjacencyList[node2index], weight);
  327.         else
  328.             adjacencyList[node1index].addNeighbor(adjacencyList[node2index], weight);
  329.     }
  330.  
  331.     void deleteEdge(int node1index, int node2index) {
  332.         adjacencyList[node1index].removeNeighbor(adjacencyList[node2index]);
  333.     }
  334.  
  335.     public void setAdjacencyListAt(int index, E x) {
  336.         adjacencyList[index].setInfo(x);
  337.     }
  338.  
  339.     public GraphNode<E>[] getAdjacencyList() {
  340.         return adjacencyList;
  341.     }
  342.  
  343.     /*************************** KRUSKAL ***********************************************************************/
  344.     public Edge[] getAllEdges() {
  345.         int totalEdges = Arrays.stream(adjacencyList).mapToInt(i -> i.getNeighbors().size()).sum();
  346.         Edge[] edges = new Edge[totalEdges];
  347.         int index = 0;
  348.         for (GraphNode<E> node : adjacencyList)
  349.             for (GraphNodeNeighbor<E> neighbor : node.getNeighbors()) {
  350.                 int index1 = node.getIndex();
  351.                 int index2 = neighbor.node.getIndex();
  352.                 int weight = neighbor.weight;
  353.                 edges[index++] = new Edge(index1, index2, weight);
  354.             }
  355.         return edges;
  356.     }
  357.  
  358.     private int[] union(int u, int v, int[] links) {
  359.         int findWhat = links[u < v ? v : u];
  360.         int replaceWith = links[u < v ? u : v];
  361.         IntStream.range(0, links.length).filter(i -> links[i] == findWhat).forEach(i -> links[i] = replaceWith);
  362.         return links;
  363.     }
  364.  
  365.     public List<Edge> kruskal() {
  366.         int[] links = new int[this.nodesCount];
  367.         Edge[] edges = this.getAllEdges();
  368.         Arrays.sort(edges);
  369.         Arrays.setAll(links, i -> i);
  370.         List<Edge> mstEdges = new ArrayList<>();
  371.         for (Edge e : edges) {
  372.             if (links[e.getFrom()] != links[e.getTo()]) {
  373.                 mstEdges.add(e);
  374.                 links = this.union(e.getFrom(), e.getTo(), links);
  375.             }
  376.             if (mstEdges.size() == (this.nodesCount - 1))
  377.                 break;
  378.         }
  379.         return mstEdges;
  380.     }
  381.  
  382.     /*******************************************************************************************************/
  383.     /************************ PRIM **************************************************************************/
  384.  
  385.     private Edge getMinimalEdge(boolean[] included) {
  386.         int index1 = Integer.MAX_VALUE, index2 = Integer.MAX_VALUE;
  387.         int minweight = Integer.MAX_VALUE;
  388.         Double myMin = Arrays.stream(adjacencyList).filter(i -> included[i.getIndex()]).flatMapToDouble(adl -> adl.getNeighbors().stream().filter(i -> !included[i.node.getIndex()]).mapToDouble(n -> n.weight)).min().orElse(0);
  389.         for (int i = 0; i < this.nodesCount; i++) {
  390.             if (included[i]) {
  391.                 for (GraphNodeNeighbor<E> pom : adjacencyList[i].getNeighbors()) {
  392.                     if (!included[pom.node.getIndex()] && pom.weight < minweight) {
  393.                         index1 = i;
  394.                         index2 = pom.node.getIndex();
  395.                         minweight = pom.weight;
  396.                     }
  397.                 }
  398.             }
  399.         }
  400.         int breakHere = 1;
  401.         System.out.println("###################");
  402.         System.out.printf("myMin %f minweight %f\n", myMin, minweight);
  403.         System.out.println(myMin == minweight);
  404.         System.out.println("###################");
  405.         return minweight < Integer.MAX_VALUE ? new Edge(index1, index2, minweight) : null;
  406.     }
  407.  
  408.     public List<Edge> prim(int start_index) {
  409.         List<Edge> mstEdges = new ArrayList<>();
  410.         boolean[] included = new boolean[this.nodesCount];
  411.         Arrays.fill(included, false);
  412.         included[start_index] = true;
  413.         for (int i = 0; i < this.nodesCount - 1; i++) {
  414.             Edge e = this.getMinimalEdge(included);
  415.             if (e == null) {
  416.                 System.out.println("Ne mozat da se povrzat site jazli");
  417.                 break;
  418.             }
  419.             included[e.getFrom()] = included[e.getTo()] = true;
  420.             mstEdges.add(e);
  421.         }
  422.         return mstEdges;
  423.     }
  424.  
  425.     /*******************************************************************************************************/
  426.     /***************** DIJKSTRA ******************************************************************************/
  427.  
  428.     public int dijkstra(int from, int to) {
  429.         int[] distance = new int[this.nodesCount];
  430.         boolean[] finalno = new boolean[this.nodesCount];
  431.         Arrays.fill(distance, -1);
  432.         Arrays.fill(finalno, false);
  433.         finalno[from] = true;
  434.         distance[from] = 0;
  435.         for (int i = 1; i < this.nodesCount; i++) {
  436.             for (GraphNodeNeighbor<E> pom : adjacencyList[from].getNeighbors()) {
  437.                 if (!finalno[pom.node.getIndex()]) {
  438.                     if (distance[pom.node.getIndex()] <= 0) {
  439.                         distance[pom.node.getIndex()] = distance[from] + pom.weight;
  440.                     } else if (distance[from] + pom.weight < distance[pom.node.getIndex()]) {
  441.                         distance[pom.node.getIndex()] = distance[from] + pom.weight;
  442.                     }
  443.                 }
  444.             }
  445.             boolean minit = false;
  446.             int k = 0;
  447.             int minc = -1;
  448.             for (int j = 0; j < this.nodesCount; j++) {
  449.                 if (!finalno[j] && distance[j] != -1) {
  450.                     if (!minit) {
  451.                         minc = distance[k = j];
  452.                         minit = true;
  453.                     } else if (minc > distance[j] && distance[j] > 0)
  454.                         minc = distance[k = j];
  455.                 }
  456.             }
  457.             finalno[from = k] = true;
  458.         }
  459.         return distance[to];
  460.     }
  461.  
  462.     /*******************************************************************************************************/
  463.  
  464.     @Override
  465.     public String toString() {
  466.         return Arrays.stream(adjacencyList).map(GraphNode::toString).collect(Collectors.joining("\n"));
  467.     }
  468. }
  469.  
  470. class Cell {
  471.     Integer x;
  472.     Integer y;
  473.     Integer dis;
  474.  
  475.     public Cell(Integer x, Integer y, Integer dis) {
  476.         this.x = x;
  477.         this.y = y;
  478.         this.dis = dis;
  479.     }
  480. }
  481.  
  482. /**
  483.  * Дадена е една шаховска табла mxn и на неа е даден една шаховска фигура - коњ поставен во некое поле (x,y) на таблата. Коњот на шаховската табла легално во еден потег може да се движи или за две позиции вертикално и една хоризонтално или за две позиции хоризонтално и една вертикално, т.е. од позиција (x,y) може да се движи на една од следните позиции (x±1,y±2) или (x±2,y±1) (види слика). Да се најде минималниот број на потези за коњот да се придвижи од едно дадено почетно поле до едно дадено крајно поле на таблата.
  484.  * <p>
  485.  * enter image description here
  486.  * <p>
  487.  * Влез: Во првиот ред од влезот се дадени бројот на редици и колони на таблата (5<=m,n<=100), а во вториот ред се дадени полињата на почетокот и крајот на движењето на коњот (x1,y1) и (x2,y2) .
  488.  * <p>
  489.  * Излез: Да се испечати минималниот број на потези за коњот да се придвижи од едно дадено почетно поле до едно дадено крајно поле на таблата.
  490.  * <p>
  491.  * Делумно решение: Задачата се смета за делумно решена доколку се поминати 4 тест примери.
  492.  * <p>
  493.  * Пример:
  494.  * <p>
  495.  * Влез:
  496.  * <p>
  497.  * 5 5
  498.  * <p>
  499.  * 1 2 4 3
  500.  * <p>
  501.  * Излез:
  502.  * <p>
  503.  * 2
  504.  * <p>
  505.  * За да коњот се придвижи од позиција (1,2) до позиција (4,3) на шаховска табла 5x5 потребни се минимум 2 потега.
  506.  * <p>
  507.  * Име на класа (Јава): Board
  508.  */
Advertisement
Add Comment
Please, Sign In to add comment