簡體   English   中英

創建具有兩種類型邊的連通圖

[英]Create a Connected Graph With Two Types Of Edges

我想構建一個連接並且只能具有水平或垂直邊緣的圖形。 邊緣是軌道/軌道開關。

  • 有兩種類型的軌道: NormalTrackTrackSwitch
    • NormalTrack:起點,終點。
    • TrackSwitch:起點、終點、第二個終點。
      • 第一個端點是可以通過的標准設置(有一個可以更改開關設置的設置開關命令)。
  • 所有軌道(switch 也是軌道)都有一個從 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和兩個子類NormalTrackTrackSwitch

  • TrackSwitch(int id, Point startPoint, Point endPoint, Point secondEndPoint, int length, boolean switchEnabled)
  • NormalTrack(int id, Point startPoint, Point endPoint, int length)

我現在如何繼續..?

您可以創建兩個類NormalTrackTrackSwitch並通過該類的實例來表示每個軌道。 這些類存儲軌道的 id、起點和終點。

然后,您可能希望為每個點存儲傳入曲目列表以及傳出曲目列表。 在此設置中,交換機有點復雜,因為它有兩個端點。 您可能還需要在交換機中使用一個標志來說明當前哪個端點處於活動狀態。 然后,當您遍歷一個點的傳入/傳出軌跡並點擊TrackSwitch您必須首先檢查您正在迭代的點當前是否處於活動狀態。 如果沒有,你必須跳過它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM