[英]Displaying shortest path via bfs search in directed graph
我一直在為一個大學項目工作,遇到了一個很大的問題。 我應該做一個函數,以通過有向圖從A點到B點獲得最短路徑,並按順序顯示路徑。
EX。 如果該節點擁有州名,並且我們想查找加利福尼亞和猶他州之間的最短路徑,則輸出將顯示加利福尼亞->內華達州->猶他州
當前,我的遍歷顯示所有使用bfs搜索的節點,而不是我們從A點到B點獲取的節點列表。
以下是我對作業的執行情況。 我唯一真正的問題是,我將如何跟蹤我實際遍歷的節點而不是搜索到的所有節點。
bool DirectedGraph::GetShortestPath(
const string& startNode, const string& endNode,
bool nodeDataInsteadOfName, vector<string>& traversalList) const
{
//Nodes are the same
if (startNode.compare(endNode) == 0)
return false;
//Stores the location of our nodes in the node list
vector<int> path;
//Queue to hold the index of the node traversed
queue<int> q;
//Create our boolean table to handle visited nodes
bool *visited = new bool[m_nodes.size()];
//initialize bool table
memset(visited, false, sizeof(bool) * m_nodes.size());
//Label the start node as visited
visited[GetNodeIndex(startNode)] = true;
//Push the node onto our queue
q.push(GetNodeIndex(startNode));
while (!q.empty())
{
//Store the nodes index
int index = q.front();
path.push_back(q.front());
q.pop();
int i = 0;
for (i = 0; i < m_nodes[index]->Out.size(); i++)
{
//If this node matches what we are looking for break/return values
if (m_nodes[index]->Out[i]->targetI == GetNodeIndex(endNode))
{
path.push_back(m_nodes[index]->Out[i]->targetI);
if (nodeDataInsteadOfName)
{
path.push_back(m_nodes[index]->Out[i]->targetI);
for (int x = 0; x < path.size(); x++)
{
traversalList.push_back(m_nodes[path[x]]->Data);
}
}
else
{
for (int x = 0; x < path.size(); x++)
{
traversalList.push_back( m_nodes[path[x]]->Name);
}
}
return true;
}
//Continue through the data
if (!visited[m_nodes[index]->Out[i]->targetI])
{
visited[m_nodes[index]->Out[i]->targetI] = true;
q.push(m_nodes[index]->Out[i]->targetI);
}
}
}
// You must implement this function
return false;
}
//定義圖私有成員
struct Edge
{
int srcI; // Index of source node
int targetI; // Index of target node
Edge(int sourceNodeIndex, int targetNodeIndex)
{
srcI = sourceNodeIndex;
targetI = targetNodeIndex;
}
};
struct Node
{
string Name;
string Data;
Node(const string& nodeName, const string& nodeData)
{
Name = nodeName;
Data = nodeData;
}
// List of incoming edges to this node
vector<Edge*> In;
// List of edges going out from this node
vector<Edge*> Out;
};
// We need a list of nodes and edges
vector<Node*> m_nodes;
vector<Edge*> m_edges;
// Used for efficiency purposes so that quick node lookups can be
// done based on node names. Maps a node name string to the index
// of the node within the nodes list (m_nodes).
unordered_map<string, int> m_nodeMap;
第一個問題是for循環中的if 。 您的path變量只能包含兩項:開始節點和結束節點。 我建議您不要使用for循環跟蹤路徑。 而是為每個節點分配一個距離。
struct Node
{
string Name;
string Data;
int Distance;
Node(const string& nodeName, const string& nodeData)
{
Name = nodeName;
Data = nodeData;
Distance = INT_MAX;
}
// List of incoming edges to this node
vector<Edge*> In;
// List of edges going out from this node
vector<Edge*> Out;
};
並在循環之前將起始節點的距離設置為零。
m_nodes[GetNodeIndex(startNode)]->Distance = 0;
在每次迭代中,從隊列中選擇一個節點(您稱為index ),遍歷其鄰接表(外向弧),並測試是否訪問了相鄰節點。 如果訪問了該節點,請跳過它。 如果未訪問該節點,則將其距離設置為
m_nodes[index]->Distance + 1
更新每個節點的距離后,檢查它是否是最后一個節點,如果是這樣,請跳出循環。
此時,您的距離已正確更新。 每次從鄰接節點向后移動,每次從(距離=當前節點的距離-1)從鄰接列表中選擇該節點。 每次您真正知道targetI時 ,都可以使用m_edges向量進行此操作,因此可以使用上述距離值檢查其對應的scrI 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.