簡體   English   中英

從起點遍歷圖形並在起點處終止C ++

[英]Traverse a graph from a starting point and ending at the starting point C++

我正在使用C ++程序,在該程序中,我們必須遍歷頂點和加權邊的圖,以這樣的方式開始:在用戶指定的頂點處開始,然后在移動了所需的距離后在同一頂點處結束。 我不確定如何用代碼來實現這一點,但到目前為止我有:

void DijkstrasShortestPath()
{
    while (vertices.size() != 0)
    {
        Vertex* u = extract_min(vertices);
        vector<Vertex*>* adjVertex = AdjVertices(u);

        const int size = adjVertex->size();
        for (int i=0; i<size; ++i)
        {
            Vertex* v = adjVertex->at(i);
            int distance = travel_dist(u, v) +
                u->distFromStart;

            if (distance < v->distFromStart)
            {
                v->distFromStart = distance;
                v->previous = u;
            }
        }
        delete adjVertex;
    }
}

Vertex* extract_min(vector<Vertex*>& vertices)
{
    int size = vertices.size();
    if (size == 0) {
        return NULL;
    }
    int minimum = 0;
    Vertex* min = vertices.at(0);
    int i = 0;
    for( i=1; i<size; ++i)
    {
        Vertex* temp = vertices.at(i);
        if( temp->distFromStart < min->distFromStart) {
            min = temp;
            minimum = i;
        }
    }
    vertices.erase(vertices.begin() + minimum);
    return min;
}

vector <Vertex*>* AdjVertices(Vertex* vert)
{
    vector<Vertex*>* adjVertex = new vector <Vertex*> ();
    const int size = edges.size();
    for(int i=0; i<size; ++i)
    {
        Edge* edge = edges.at(i);
        Vertex* adjacent = NULL;
        if (edge->intersection1 == vert)
        {
            adjacent = edge->intersection2;
        }
        else if (edge->intersection2 == vert)
        {
            adjacent = edge->intersection1;
        }
        if (adjacent && vertices_check(vertices, adjacent))
        {
            adjVertex->push_back(adjacent);
        }
    }
    return adjVertex;
}

int travel_dist(Vertex* u, Vertex* v)
{
    const int size = edges.size();
    for(int i=0; i<size; ++i)
    {
        Edge* edge = edges.at(i);
        if (edge->street_connection(u, v))
        {
            return edge->distance;
        }
    }
    return -1;
}

bool vertices_check(vector<Vertex*>& vertices, Vertex* vert)
{
    const int size = vertices.size();
    for(int i=0; i<size; ++i)
    {
        if (vert == vertices.at(i))
        {
            return true;
        }
    }
    return false;
}

這本質上是Dijkstra的最短路徑算法,這並不是我想要的。 我正在嘗試做的是獲取程序以計算距離在用戶指定距離的1個單位內並且在同一頂點處開始和結束的路線。 有什么辦法可以改變我擁有的東西嗎?

這是否需要廣度優先搜索或深度優先搜索而不是Dijkstra的算法?

Dijkstra的算法將僅存儲從起始節點到任何其他節點的最短路徑。 相反,您想要的是跟蹤通往節點的所有路徑。 如果有的話,則可以在每次找到節點的新路徑時檢查是否找到了一條路徑,該路徑的長度加上新路徑的長度在用戶指定距離的一個單位內。 如果然后向前走一條路徑,向后走另一條路徑,您就會遇到麻煩。

一種可能的方法。

您可以使用有界的best-first search

創建一個結構P ,該結構存儲形成潛在回路的節點列表以及迄今創建的回路的長度。

通過為S鏈接到的每個節點創建一個單獨的P結構,在指定的頂點S播種搜索。 將這些P結構添加到優先級隊列中,該隊列按P結構描述的路徑長度排序。

考慮這些節點中的每一個依次從優先級隊列中刪除其P結構,復制其P結構並附加它們鏈接到的節點。 如果要添加的節點已經存在於P結構中,而不是不是S ,則丟棄該結構並且不再考慮該路由。 同樣,如果有任何路徑超出指定的成本C ,則放棄該路徑,不再考慮。 如果尚未丟棄路徑,則將其關聯的P結構添加到優先級隊列中。

如果S確實兩次出現在P結構中,並且P結構描述的路徑長度在允許的范圍內,則成功退出。 如果不是,請繼續搜索,直到優先隊列為空。

通過使用允許的啟發式方法來猜測給定節點到S的距離,將其添加到已確定的進行中路徑的成本中,然后使用總和作為優先級隊列的排序關鍵字,您也許可以加快算法的運行速度。 此類啟發式算法是A *算法的核心,您可能會感興趣。

這清楚嗎? 如果沒有,我可以寫一個簡短的示例代碼。

暫無
暫無

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

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