Returning name of lowest node

纵饮孤独 提交于 2020-01-25 06:42:22

问题


First of all, this is part of a university course, so whilst a copy-paste solution would do, I'm looking for a bit more depth. I'll be seeing my supervisor tomorrow anyways though.

Now onto the problem. I am implementing Dijkstra's algorithm for 5 linked nodes, A-E, which have their associated costs and links stored in a vector;

struct Node
{
    char nodeLink;  //adjacent link
    int cost;       //cost of a link
};                  //to use in Dijkstra algorithm


class HeadNode
{
public:
    char Name;
    bool Visited;
    vector<Node> nodes;
    HeadNode(char x) { Name = x; Visited = false; }

};

class Graph
{
    char Start = 'A';
    char StartNode;
    char CurrentNode;
    char Destination = 'E';
    int TotalCost = 0;
    vector<HeadNode> hnode;
    vector<char> path;
    vector<int> weight;

public:
    Graph();
    void createHeadNode(char X);
    void createAdjMatrix();
    char LeastDistance(char node);
    void printAdjMatrix();
    void Dijkstra(char StartNode);
    char GetStartNode();
};



int main()
{   
    Graph graph;
    graph.createHeadNode('A');
    graph.createHeadNode('B');
    graph.createHeadNode('C');
    graph.createHeadNode('D');
    graph.createHeadNode('E');

    graph.createAdjMatrix();
    //graph.printAdjMatrix();
    graph.Dijkstra(graph.GetStartNode());

    system("pause");
    return 0;
}

Graph::Graph()
{
}


void Graph::createHeadNode(char x)
{
    hnode.push_back(x);

}

In order to properly implement the algorithm, I have created a precursor function, LeastDistance(), within the class graph. I also have a function to get the start node, but that isn't particularly important here;

char Graph::LeastDistance(char node)
{
    int smallest = 9999;
    char smallestNode;

    for (int i = 0; i < hnode.size(); i++)
    {
        for (int j = 0; j < hnode[i].nodes.size(); ++j)
        {
            if ((node == hnode[i].Name) && (hnode[i].nodes[j].cost <= smallest) && (hnode[i].Visited == false))
            {
                smallest = hnode[i].nodes[j].cost;
                smallestNode = hnode[i].nodes[j].nodeLink;
            }
            else
            {
                hnode[i].Visited = true;
                break;
            }
        }
    }
    TotalCost = TotalCost + smallest;
    return(smallestNode);
}

void Graph::Dijkstra(char StartNode)
{
    CurrentNode = StartNode;
    if (CurrentNode == Destination)
    {
        cout << "the start is the destination, therefore the cost will be 0." << endl;
    }
    else
    {
        while(true)
        {
            if (CurrentNode != Destination)
            {
                CurrentNode = LeastDistance(StartNode);
                cout << CurrentNode << "<-";
            }
            else if (CurrentNode == Destination)
            {
                cout << endl;
                cout << "The total cost of this path is:" << TotalCost;
                TotalCost = 0;//reset cost
                break;
            }
        }
    }

}

My problem is that the LeastDistance fucntion appears always to return node C, leading to it being printed over and over, so it fills the console. So far, I have tried to debug using visual studio 2017, but I cant make much sense out of the watches. I have also tweaked the order of the breaks around, and tried to make sure the visited flag is being set to true. whether any precedence of operations is affecting this I am not sure.

Thanks in advance.


回答1:


I would contend that there are multiple problems with the way you implement this... but I think the one that's causing you the problem you describe is the statement right here:

if (CurrentNode != Destination)
{
    CurrentNode = LeastDistance(StartNode);
    cout << CurrentNode << "<-";
}

Think about what this does. Let's say your first node isn't the one you're looking for, then you call least distance and find the next smallest node. Then you print it. Then you iterate on the while loop again only to find that CurrentNode isn't the one you're looking for, so you call LeastDistance(StartNode) again, which will return the exactly same value. Thus, you'll keep printing the same result which apparently is c.

Assuming everything else is correct, I think you want:

CurrentNode = LeastDistance(CurrentNode);


来源:https://stackoverflow.com/questions/50593772/returning-name-of-lowest-node

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!