[英]Create a Connected Graph With Two Types Of Edges
我想構建一個連接並且只能具有水平或垂直邊緣的圖形。 邊緣是軌道/軌道開關。
NormalTrack
和TrackSwitch
。
這是一個示例以及圖形的外觀:
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)
我現在如何繼續..?
您可以創建兩個類NormalTrack
和TrackSwitch
並通過該類的實例來表示每個軌道。 這些類存儲軌道的 id、起點和終點。
然后,您可能希望為每個點存儲傳入曲目列表以及傳出曲目列表。 在此設置中,交換機有點復雜,因為它有兩個端點。 您可能還需要在交換機中使用一個標志來說明當前哪個端點處於活動狀態。 然后,當您遍歷一個點的傳入/傳出軌跡並點擊TrackSwitch
您必須首先檢查您正在迭代的點當前是否處於活動狀態。 如果沒有,你必須跳過它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.