Алгоритм Дейкстры + Builder pattern - Java

516
26 февраля 2017, 08:10

Дали задание реализовать паттерн 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 {
}

}

READ ALSO
Как узнать какая кнопка нажата?(java)

Как узнать какая кнопка нажата?(java)

Есть форма, на этой форме есть кнопкиИх может быть и 100 и 200 и т

462
Замена данных по шаблону Java RegExp

Замена данных по шаблону Java RegExp

Подскажите пожалуйста как сделать замену подстроки в строк путем регулярных выражений? В тексте (html) есть так называемые переменные по которым...

394
Как преобразовать XML to Java?

Как преобразовать XML to Java?

На сервер приходит xml-файл:

294
Подсказки в окне программы

Подсказки в окне программы

Мне нужно, чтобы у моей программы появилась кнопка "вопрос" желательно в следующем месте: (обозначено красным) , чтобы, если нажать на неё, потом,...

281