Дали задание реализовать паттерн Builder для алгоритма Дейкстры, что бы объект Graph был immutable, и были методы нахождения кратчайшего пути. Я написал это недорозумение, но я очень недоволен кодом, подскажите как это можно оптимизировать или изменить чтобы при создании графа можно было просто сделать Graph graph = new Graph().edge (1, 2 ,44). edge (1, 3, 65)...build(); нужна помощь)
public class Edge {
private final Vertex start;
private final Vertex finish;
private final int weight;
public Edge(String laneId, Vertex source, Vertex destination, int weight) {
this.start = source;
this.finish = destination;
this.weight = weight;
}
public Vertex getFinish() {
return finish;
}
public Vertex getStart() {
return start;
}
public int getWeight() {
return weight;
}
}
public class Vertex { final private String id; final private String name;
public Vertex(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Vertex other = (Vertex) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return name;
}
} public class Dejkstra { private final List nodes; private final List edges; private Set settledNodes; private Set unSettledNodes; private Map predecessors; private Map distance;
public Dejkstra(Graph graph) {
this.nodes = new ArrayList<Vertex>(graph.getVertexes());
this.edges = new ArrayList<Edge>(graph.getEdges());
}
public void execute(Vertex source) {
settledNodes = new HashSet<Vertex>();
unSettledNodes = new HashSet<Vertex>();
distance = new HashMap<Vertex, Integer>();
predecessors = new HashMap<Vertex, Vertex>();
distance.put(source, 0);
unSettledNodes.add(source);
while (unSettledNodes.size() > 0) {
Vertex node = getMinimum(unSettledNodes);
settledNodes.add(node);
unSettledNodes.remove(node);
findMinimalDistances(node);
}
}
private void findMinimalDistances(Vertex node) {
List<Vertex> adjacentNodes = getNeighbors(node);
for (Vertex target : adjacentNodes) {
if (getShortestDistance(target) > getShortestDistance(node)
+ getDistance(node, target)) {
distance.put(target, getShortestDistance(node)
+ getDistance(node, target));
predecessors.put(target, node);
unSettledNodes.add(target);
}
}
}
private int getDistance(Vertex node, Vertex target) {
for (Edge edge : edges) {
if (edge.getStart().equals(node)
&& edge.getFinish().equals(target)) {
return edge.getWeight();
}
}
throw new RuntimeException("Should not happen");
}
private List<Vertex> getNeighbors(Vertex node) {
List<Vertex> neighbors = new ArrayList<Vertex>();
for (Edge edge : edges) {
if (edge.getStart().equals(node)
&& !isSettled(edge.getFinish())) {
neighbors.add(edge.getFinish());
}
}
return neighbors;
}
private Vertex getMinimum(Set<Vertex> vertexes) {
Vertex minimum = null;
for (Vertex vertex : vertexes) {
if (minimum == null) {
minimum = vertex;
} else {
if (getShortestDistance(vertex) < getShortestDistance(minimum)) {
minimum = vertex;
}
}
}
return minimum;
}
private boolean isSettled(Vertex vertex) {
return settledNodes.contains(vertex);
}
private int getShortestDistance(Vertex destination) {
Integer d = distance.get(destination);
if (d == null) {
return Integer.MAX_VALUE;
} else {
return d;
}
}
public LinkedList<Vertex> getPath(Vertex target) {
LinkedList<Vertex> path = new LinkedList<Vertex>();
Vertex step = target;
if (predecessors.get(step) == null) {
return null;
}
path.add(step);
while (predecessors.get(step) != null) {
step = predecessors.get(step);
path.add(step);
}
Collections.reverse(path);
return path;
}
} public class Graph { private final List vertexes; private final List edges;
public List<Edge> getEdges() {
return edges;
}
public List<Vertex> getVertexes(){
return vertexes;
}
public static class Builder {
private List<Vertex> vertexes;
private List<Edge> edges;
public Builder edge(List<Vertex> vertexes, List<Edge> edges) {
this.vertexes = vertexes;
this.edges = edges;
return this;
}
public Graph build() {
return new Graph(this);
}
}
Graph(Builder builder) {
vertexes = builder.vertexes;
edges = builder.edges;
}
} public class Test { private List nodes; private List edges;
@org.junit.Test
public void testExcute() {
nodes = new ArrayList<Vertex>();
edges = new ArrayList<Edge>();
for (int i = 0; i < 12; i++) {
Vertex location = new Vertex("Node_" + i, "Node_" + i);
nodes.add(location);
}
addLane("Edge_0", 1, 2, 70);
addLane("Edge_1", 1, 3, 140);
addLane("Edge_2", 1, 4, 120);
addLane("Edge_3", 2, 5, 130);
addLane("Edge_4", 3, 4, 80);
addLane("Edge_5", 3, 6, 100);
addLane("Edge_6", 4, 5, 140);
addLane("Edge_7", 4, 6, 100);
addLane("Edge_8", 4, 8, 150);
addLane("Edge_9", 5, 7, 150);
addLane("Edge_10", 6, 7, 170);
addLane("Edge_11", 6, 8, 70);
addLane("Edge_12", 7, 8, 90);
Graph graph = new Graph.Builder().edge(nodes, edges).build();
Dejkstra dijkstra = new Dejkstra(graph);
dijkstra.execute(nodes.get(0));
LinkedList<Vertex> path = dijkstra.getPath(nodes.get(7));
assertNotNull(path);
assertTrue(path.size() > 0);
for (Vertex vertex : path) {
System.out.println(vertex);
}
}
private void addLane(String laneId, int sourceLocNo, int destLocNo,
int duration) {
Edge lane = new Edge(laneId, nodes.get(sourceLocNo), nodes.get(destLocNo), duration);
edges.add(lane);
}
public static void main(String[] args) throws IOException {
}
}
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости