diff --git a/Java4L7HW/src/alexrm84/Graph.java b/Java4L7HW/src/alexrm84/Graph.java new file mode 100644 index 0000000..273276a --- /dev/null +++ b/Java4L7HW/src/alexrm84/Graph.java @@ -0,0 +1,180 @@ +package alexrm84; + +import java.util.*; +import java.util.stream.Stream; + +public class Graph { + + private final List vertices = new ArrayList<>(); + private boolean[][] adjMat; + + private int size; + + public Graph(int maxVertexCount) { + this.adjMat = new boolean[maxVertexCount][maxVertexCount]; + } + + public void addVertex(String label){ + vertices.add(new Vertex(label)); + size++; + } + + private int indexOf(String start){ + for (int i = 0; i < size; i++) { + if (vertices.get(i).getLabel().equals(start)){ + return i; + } + } + return -1; + } + + private boolean find(String start){ + return indexOf(start)!=-1; + } + + private boolean areAllExist(String start, String... others){ + String[] allLabels = Arrays.copyOf(others,others.length+1); + allLabels[allLabels.length-1]=start; + return areAllExist(allLabels); + } + + private boolean areAllExist(String... others){ + return Stream.of(others).allMatch(this::find); + } + + public void addEdge(String start, String finish){ + if (!find(start)|| !find(finish)){ + throw new IllegalArgumentException(String.format("Invalid label for vertex: [%s,%s]", start,finish)); + } + + int startIndex = indexOf(start); + int finishIndex = indexOf(finish); + adjMat[startIndex][finishIndex]=true; + adjMat[finishIndex][startIndex]=true; + } + + public void addEdges(String start, String... others){ + if (!areAllExist(start,others)){ + throw new IllegalArgumentException("Invalid params"); + } + + int startIndex = indexOf(start); + for (int i = 0; i < others.length; i++) { + int finishIndex = indexOf(others[i]); + adjMat[startIndex][finishIndex]=true; + adjMat[finishIndex][startIndex]=true; + } + } + + public void display(){ + for (int i = 0; i < size; i++) { + System.out.print(vertices.get(i)); + for (int j = 0; j < size; j++) { + if (adjMat[i][j]){ + System.out.print(" -> " + vertices.get(j)); + } + } + System.out.println(); + } + } + + public void dfs(String startLabel){ + if (!find(startLabel)){ + throw new IllegalArgumentException("Invalid start label: " + startLabel); + } + + Stack stack = new Stack<>(); + Vertex vertex = vertices.get(indexOf(startLabel)); + visitVertex(stack,vertex); + + while (!stack.isEmpty()){ + vertex=getNearUnvisitedVertex(stack.peek()); + if (vertex==null){ + stack.pop(); + continue; + } + visitVertex(stack,vertex); + } + } + + public void bfs(String startLabel){ + if (!find(startLabel)){ + throw new IllegalArgumentException("Invalid start label: " + startLabel); + } + + Queue queue = new LinkedList<>(); + Vertex vertex = vertices.get(indexOf(startLabel)); + visitVertex(queue,vertex); + + while (!queue.isEmpty()){ + vertex=getNearUnvisitedVertex(queue.peek()); + if (vertex==null){ + queue.remove(); + continue; + } + visitVertex(queue,vertex); + } + } + + public void bfsFindRoute(String startLabel, String finishLabel){ + if (!find(startLabel)|| !find(finishLabel)){ + throw new IllegalArgumentException(String.format("Invalid label for vertex: [%s,%s]", startLabel,finishLabel)); + } + Queue queue = new LinkedList<>(); + Vertex vertex = vertices.get(indexOf(startLabel)); + visitVertex(queue,vertex); + while (!queue.isEmpty()){ + vertex=getNearUnvisitedVertex(queue.peek()); + if (vertex==null){ + queue.remove(); + continue; + } + vertex.setPreviousCity(queue.peek()); + if (vertex.getLabel().equals(finishLabel)){ + showRoute(finishLabel); + return; + } + visitVertex(queue,vertex); + } + } + + private Vertex getNearUnvisitedVertex(Vertex peek) { + int peekIndex=vertices.indexOf(peek); + for (int i = 0; i < size; i++) { + if (adjMat[peekIndex][i] && !vertices.get(i).isWasVisited()){ + return vertices.get(i); + } + } + return null; + } + + private void visitVertex(Stack stack, Vertex vertex) { + displayVertex(vertex); + stack.push(vertex); + vertex.markAsVisited(); + } + + private void visitVertex(Queue stack, Vertex vertex) { +// displayVertex(vertex); + stack.add(vertex); + vertex.markAsVisited(); + } + + private void displayVertex(Vertex vertex) { + System.out.println(vertex); + } + + private void showRoute(String label){ + Vertex vertex=vertices.get(indexOf(label)); + Stack stack= new Stack<>(); + while (vertex.getPreviousCity()!=null){ + stack.push(vertex.getPreviousCity().getLabel()); + vertex=vertex.getPreviousCity(); + } + stack.pop(); + System.out.println("Самый короткий путь от города "+vertex.getLabel()+" до города "+label+" пройдет по следущим городам: "); + while (!stack.isEmpty()){ + System.out.print(stack.pop()+" "); + } + } +} diff --git a/Java4L7HW/src/alexrm84/Main.java b/Java4L7HW/src/alexrm84/Main.java new file mode 100644 index 0000000..957d3b5 --- /dev/null +++ b/Java4L7HW/src/alexrm84/Main.java @@ -0,0 +1,34 @@ +package alexrm84; + +public class Main { + + public static void main(String[] args) { + testBfs(); + } + + private static void testBfs() { + Graph graph = new Graph(10); + graph.addVertex("Москва"); + graph.addVertex("Тула"); + graph.addVertex("Рязань"); + graph.addVertex("Калуга"); + graph.addVertex("Липецк"); + graph.addVertex("Тамбов"); + graph.addVertex("Орел"); + graph.addVertex("Саратов"); + graph.addVertex("Курск"); + graph.addVertex("Воронеж"); + + graph.addEdges("Москва", "Тула", "Рязань", "Калуга"); + graph.addEdge("Тула", "Липецк"); + graph.addEdge("Липецк", "Воронеж"); + graph.addEdge("Калуга", "Орел"); + graph.addEdge("Орел", "Курск"); + graph.addEdge("Курск", "Воронеж"); + graph.addEdge("Рязань", "Тамбов"); + graph.addEdge("Тамбов", "Саратов"); + graph.addEdge("Саратов", "Воронеж"); + + graph.bfsFindRoute("Москва","Воронеж"); + } +} diff --git a/Java4L7HW/src/alexrm84/Vertex.java b/Java4L7HW/src/alexrm84/Vertex.java new file mode 100644 index 0000000..b58c0e4 --- /dev/null +++ b/Java4L7HW/src/alexrm84/Vertex.java @@ -0,0 +1,58 @@ +package alexrm84; + +import java.util.Objects; + +public class Vertex { + + private final String label; + private Vertex previousCity; + private boolean wasVisited; + + public Vertex getPreviousCity() { + return previousCity; + } + + public void setPreviousCity(Vertex previousCity) { + this.previousCity = previousCity; + } + + public Vertex(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public boolean isWasVisited() { + return wasVisited; + } + + public void resetState() { + this.wasVisited = false; + } + + public void markAsVisited(){ + this.wasVisited=true; + } + + @Override + public String toString() { + return "Vertex{" + + "label='" + label + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Vertex vertex = (Vertex) o; + return Objects.equals(label, vertex.label); + } + + @Override + public int hashCode() { + return Objects.hash(label); + } +}