Нахождение пути от начала до конца путем обхода графа - PullRequest
0 голосов
/ 29 ноября 2018

В настоящее время я выполняю школьное задание, которое требует, чтобы мы смоделировали карту автобусного маршрута с использованием графиков (ненаправленных), где края представляют дороги, на которых есть метки, обозначенные буквой автобусного маршрута (одна дорога может иметь автобус a, а другая -может иметь шину b), и узлы представляют пересечения, тупик или начальные и конечные местоположения.Карта имеет формат прямоугольной / квадратной сетки, поэтому максимальное количество инцидентных ребер, которые может иметь узел, равно 4 (это означает, что к перекрестку подключено 4 дороги).

Я реализовал Node, Edge иГрафики классов, а также удалось добавить все ребра и узлы, необходимые для графа, представляющего образец карты.Теперь мне нужно написать метод, который использует Iterator, который хранит все инцидентные ребра узла и целочисленное значение, представляющее, сколько разрешений на изменение шины, и проходит через график, чтобы найти ОДИН путь, который ведет от начального узла кконечный узел без использования большего количества изменений шины, чем указано.Затем верните Итератор, в котором хранятся все узлы, переданные по пути от начала до конца.

Это то, что у меня есть до сих пор для метода (незавершенного, поскольку я застрял):

public Iterator<GraphNode> trip() throws GraphException {
    GraphNode startNode = new GraphNode(startLoc); //Creates the starting node.
    listOfNodes.add(startNode); //Adds the starting node to the list of nodes that will be the solution.
    startNode.setMark(true); //Marks the starting node as true, meaning it has been visited.
    pathForEveryNode(graph.incidentEdges(startNode)); //Uses the custom method to find where to go next.
    return listOfNodes.iterator(); //Returns the iterator that stores the solution nodes.
}

private List<GraphNode> pathForEveryNode (Iterator<GraphEdge> incidentEdges) throws GraphException {
    //This checks if the current node has incident edges or not, if not, then null is returned.
    if (incidentEdges == null) {
        return null;
    } else {
        //If the current node does have incident nodes, check the first edge first.
        while (incidentEdges.hasNext()) {
            tryAgain:{ GraphEdge nextEdge = incidentEdges.next(); //The is the first edge to be checked.
                GraphNode endNode = nextEdge.secondEndpoint(); //This is the second end point of the current edge.
                /*
                 * Checks if the current edge and one of the edges connected to the second end point has
                 * the same bus route set. If not, then the number of changes needs to be checked, if it is,
                 * then add the second end point to the array list and move to the next set of incident edges.
                 */
                listOfNodes.add(endNode); //Adds the second end point to the array list.
                endNode.setMark(true); //Marks the second end point as true, meaning it has been visited.
                tryAgain2:{GraphEdge Snode = graph.incidentEdges(endNode).next();
                if (nextEdge.getBusLine() != Snode.getBusLine()) {
                    /*
                     * If the number of changes left is larger or equal to 1, it is decreased by 1. Otherwise,
                     * there is not enough changes left, so back track to the beginning and try the next edge available.
                     */
                    if (kNumOfChanges >= 1) {
                        kNumOfChanges--;
                        listOfNodes.add(Snode.secondEndpoint()); //Adds the second end point to the array list.
                        Snode.secondEndpoint().setMark(true); //Marks the second end point as true, meaning it has been visited.
                    } else if(kNumOfChanges == 0 && graph.incidentEdges(endNode).hasNext()){ //If the number of changes available or remaining is 0:
                        break tryAgain2; //Try a different edge connecting to the endNode.
                    } else if(kNumOfChanges == 0 && !graph.incidentEdges(endNode).hasNext()) {
                        listOfNodes.remove(endNode); //So the node is removed.
                        endNode.setMark(false); //Marks the second end point to false, meaning it has not been visited.
                        break tryAgain; //Try a different incident edge.
                    }
                } else {
                    listOfNodes.add(Snode.secondEndpoint()); //Adds the second end point to the array list.
                    Snode.secondEndpoint().setMark(true); //Marks the second end point as true, meaning it has been visited.
                }

                //If the second end point of the current node is the ending node, return the array list and end the program.
                if (Snode.secondEndpoint().getName() == endLoc) {
                    return listOfNodes;
                /*
                 * If it is not the ending node, check if all of its edges leads to an unmarked node (nodes that has not been visited).
                 * If there are no nodes that is unmarked (deadend), then this current node doesn't lead any where, so remove it from the 
                 * array list.
                 */
                } else if (pathForEveryNode(allPathPossibilitiesOneNode(graph.incidentEdges(Snode.secondEndpoint()))) == null) {
                    listOfNodes.remove(Snode.secondEndpoint()); //remove the current node from the array list.
                    Snode.secondEndpoint().setMark(false); //Marks the current node to be false, meaning it has not been visited.
                    listOfNodes.remove(endNode); //So the node is removed.
                    endNode.setMark(false); //Marks the second end point to false, meaning it has not been visited.
                    if (kNumOfChanges > 1) {
                        kNumOfChanges++;
                    }
                }

                //Checks if the array list contains the ending node, if it does, then return the array list. Otherwise, return null.
                boolean endLocInArray = false;
                for(int i = 0; i < listOfNodes.size(); i++) {
                    if (listOfNodes.get(i).getName() == endLoc) {
                        endLocInArray = true;
                        break;
                    }
                }

                if(endLocInArray == true) {
                    return listOfNodes;
                }
            }}
        }
    }
    return null;
}

и вспомогательный метод, который проверяет, была ли уже посещена вторая конечная точка:

private Iterator<GraphEdge> allPathPossibilitiesOneNode(Iterator<GraphEdge> PossibilitiesIterator) {
    List<GraphEdge> allPathPossibilities = new ArrayList<GraphEdge>(); //Initializes the array list that will store the edges.
    //This loop goes through all the incident edges connecting to the current node.
    while (PossibilitiesIterator.hasNext()) {
        GraphEdge currentEdge = PossibilitiesIterator.next(); //The first incident edge.
        //This checks if the second end point (next intersection) is marked or not, if not, then add it to the array list.
        if (currentEdge.secondEndpoint().getMark() == false) {
            allPathPossibilities.add(currentEdge);
        }
    }
    //Return the iterator is the array list is not empty, otherwise return null.
    if (!allPathPossibilities.isEmpty()) {
        return allPathPossibilities.iterator();
    } else {
        return null;
    }
}

Предполагается сравнить метки busLine ребра, соединенного с первым узлом (firstEndPoint), сребро, подключенное ко второй конечной точке первого ребра, чтобы увидеть, одинаковы ли автобусные маршруты, если они не совпадают, то проверьте, достаточно ли осталось изменений в шине.

То, что у меня есть, работает без ошибок, но распечатанное решение - это уже пустой список, хотя и не должно быть.

Мы только что начали тему на графиках и предназначены для назначения.

Редактировать: пример графика и решения:

enter image description here

Путь для этого маршрута карты составляет 0,1,5,6,10 для узлов, если разрешена 1 смена шины.

...