Я хочу построить график, который связан и может иметь только горизонтальные или вертикальные ребра. Края - это треки / переключатели треков.
- Существует два типа треков:
NormalTrack
и TrackSwitch
. - NormalTrack: startPoint, endPoint.
- TrackSwitch: startPoint, endPoint, secondEndPoint.
- Первая конечная точка - это стандартная настройка, которая может быть пройдена (есть команда переключателя установки, которая может изменить настройку переключателя).
- Все дорожки (переключатель также является дорожкой) имеют уникальный идентификатор, начинающийся с 1.
- За исключением первой дорожки, начальная или конечная точка всегда должна быть подключена к начальной или конечной точке существующей дорожки. Только одна другая дорожка (обычная дорожка или переключатель дорожки) может быть подключена к точке на дорожке.
Вот пример и то, как будет выглядеть график:
add track (1,1) -> (5,1)
ID -> 1
add switch (5,1) -> (8,1),(5,3)
ID -> 2
add track (1,1) -> (1,-3)
ID -> 3
add track (1,-3) -> (10,-3)
ID -> 4
add track (8,1) -> (10,1)
ID -> 5
add track (10,1) -> (10,-3)
ID -> 6
add track (5,3) -> (8,3)
ID -> 7
У меня есть класс Point
, который представляет декартову точку, и класс RailNetwork
, где я собираюсь реализовать график. В моем классе Register
у меня есть Map<Integer, Track> tracks;
, в котором я сохраняю все треки. В этом классе я также создал RailNetwork network = new RailNetwork();
. Я уже реализовал командный интерфейс. Теперь я хочу создать железнодорожную сеть.
Может кто-нибудь показать мне, как реализовать этот способ?
РЕДАКТИРОВАТЬ
Вот моя текущая реализация :
public class RailNetwork {
private Map<Point, List<Point>> edges = new HashMap<>();
// Add edge (two points)
public void addEdge(Point firstCoordinate, Point secondCoordinate) {
edges.computeIfAbsent(firstCoordinate, x -> new ArrayList<>()).add(secondCoordinate);
edges.computeIfAbsent(secondCoordinate, x -> new ArrayList<>()).add(firstCoordinate);
}
// Return all edges
public List<Point> getEdges(Point node) {
return Collections.unmodifiableList(edges.get(node));
}
// Check if a set of edges is still connected after removing them
public boolean isConnectedAfterRemoving(Set<Edge> toRemove) {
Set<Point> notVisited = edges.entrySet()
.stream()
.filter(e -> e.getValue().stream().anyMatch(d -> !toRemove.contains(new Edge(e, d)) &&
!toRemove.contains(new Edge(d, e))))
.map(Map.Entry::getKey).collect(java.util.stream.Collectors.toSet());
if (notVisited.isEmpty())
return true;
visit(notVisited.iterator().next(), notVisited, toRemove);
return notVisited.isEmpty();
}
private void visit(Point next, Set<Point> notVisited, Set<Edge> toRemove) {
if (!notVisited.remove(next))
return;
for (Point point : edges.get(next))
if (!toRemove.contains(new Edge(next, point)) &&
!toRemove.contains(new Edge(point, next)))
visit(point, notVisited, toRemove);
}
private void visitAndRemove(Set<Point> nodes, Point node) {
if (nodes.contains(node)) {
nodes.remove(node);
List<Point> nextNodes = getEdges(node);
for (Point next : nextNodes) {
visitAndRemove(nodes, next);
}
}
}
}
public class Edge {
private final Point source;
private final Point dest;
public Edge(Point source, Point dest) {
this.source = source;
this.dest = dest;
}
@Override
public boolean equals(Object o) {
if (o == this || !(o instanceof Edge)) {
return o == this;
}
Edge edge = (Edge) o;
return Objects.equals(source, edge.source) &&
Objects.equals(dest, edge.dest);
}
@Override
public int hashCode() {
return Objects.hash(source, dest);
}
}
Я не уверен, почему мой метод isConnectedAfterRemoving()
не работает. Как я могу это исправить?
У меня также есть абстрактный класс Track
и два подкласса NormalTrack
и TrackSwitch
.
TrackSwitch(int id, Point startPoint, Point endPoint, Point secondEndPoint, int length, boolean switchEnabled)
NormalTrack(int id, Point startPoint, Point endPoint, int length)
Как мне продолжить ..?