簡體   English   中英

如何使 DFS 算法繼續在圖上工作

[英]How to make DFS algorithm continue working on a graph

我正在嘗試在 40 x 20 圖表上搜索路徑(不一定是最短路徑)。 起點和終點是隨機選擇的。 DFS 工作正常,直到它擊中和邊緣。 然后,它不會返回並嘗試朝不同的方向搜索,而是自行循環。 這是我的代碼(一小部分,但不再需要理解它,完整代碼在這里:

struct Wierzcholek {
    Wierzcholek* next;
    int numerwierzcholka;
};
bool DFS(Wierzcholek**& TablicaList, bool*& visited, int& startowy, int koncowy, int MacierzGrafu[Wymiar40][Wymiar20])

{
        Wierzcholek* p;
        visited[startowy] = true;

            cout << setw(3) << startowy << "->";
            /*
            if (startowy == koncowy)
            {
                cout << koncowy << setw(5) << "Function has ended";
                return true;
            }//*/
                for (p = TablicaList[startowy]; p; p = p->next)
                {
                    MacierzGrafu[startowy / 20][startowy % 20] = 2;
                    if (!visited[p->numerwierzcholka])
                        if(DFS(TablicaList, visited, p->numerwierzcholka, koncowy, MacierzGrafu));
                    return true;
                }
            return false;
}
//Here's the implementation in main function
do {
        DFS(TablicaList, visited, LosowyWierzcholek, KoncowyWierzcholek, MacierzGrafu);
            if (LosowyWierzcholek == KoncowyWierzcholek)
                break;
    } while(true);

編輯:這是完整的程序: https://ideone.com/LGAhw1這是我制作鄰接列表的方法:

void UwtorzSasiada(int MacierzGrafu[Wymiar40][Wymiar20], Wierzcholek **& TablicaList,const char Kierunek, int row, int column) // 68-D(1) 71-G(4) 76-L(9) 80-P(13)
{
    Wierzcholek* p;
    int variable = int(Kierunek) - 67;
    switch (variable)
    {
    case 1: {
        if (MacierzGrafu[row + 1][column] == 1)
        {
            p = new Wierzcholek;
            p->numerwierzcholka = (((row + 1) * Wymiar20) + column);
            p->next = TablicaList[(row * Wymiar20) + column];
            TablicaList[(row * Wymiar20) + column] = p;
        }
    }break;
    case 4: {
        if (MacierzGrafu[row - 1][column] == 1)
        {
            p = new Wierzcholek;
            p->numerwierzcholka = (((row - 1) * Wymiar20) + column);
            p->next = TablicaList[(row * Wymiar20) + column];
            TablicaList[(row * Wymiar20) + column] = p;
        }
    }break;
    case 9: {
        if (MacierzGrafu[row][column - 1] == 1)
        {
            p = new Wierzcholek;
            p->numerwierzcholka = ((row * Wymiar20) + column - 1);
            p->next = TablicaList[(row * Wymiar20) + column];
            TablicaList[(row * Wymiar20) + column] = p;
        }
    }break;
    case 13: {
        if (MacierzGrafu[row][column + 1] == 1)
        {
            p = new Wierzcholek;
            p->numerwierzcholka = ((row * Wymiar20) + column + 1);
            p->next = TablicaList[(row * Wymiar20) + column];
            TablicaList[(row * Wymiar20) + column] = p;
        }
    }break;
    }
}

幾個問題:

  1. 您將遞歸的基本情況放在注釋中,但需要以積極的結果結束遞歸:

     if (startowy == koncowy) { cout << koncowy << setw(5) << "target found"; return true; }
  2. 遞歸DFS調用的結果將被忽略,而是無條件返回true —— 即使節點的鄰居已經被訪問過。 發生這種情況是因為內部if語句沒有正文:

     if (,visited[p->numerwierzcholka]) if(DFS(TablicaList, visited, p->numerwierzcholka, koncowy; MacierzGrafu)); return true;

    if右側的分號破壞了算法。 這應該是:

     if (,visited[p->numerwierzcholka] && DFS(TablicaList, visited, p->numerwierzcholka, koncowy; MacierzGrafu)) return true;
  3. startowy參數在DFS調用期間永遠不會更改,但在您的主代碼中,您似乎期望調用將更改LosowyWierzcholek直到它最終匹配KoncowyWierzcholek 這不是真的。 LosowyWierzcholek不會改變。 所以主程序中的while循環是一個無限循環。

  4. 主程序根本不需要循環:遍歷是通過遞歸發生的,而不是通過迭代發生的。 再次重復相同的DFS搜索無濟於事。

    相反,您的主程序應該只調用DFS並使用 boolean 返回值:

     bool result = DFS(TablicaList, visited, LosowyWierzcholek, KoncowyWierzcholek, MacierzGrafu); cout << "result: " << result;

暫無
暫無

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

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