İki verilen düğüm arasındaki yolları bulun?

oy
42

Ben verilen noktalar arasında var yolları ve yol detayları sayısına varmak, nasıl ben aşağıda bir tarzda bağlanmış düğümleri var ki?

1,2 //node 1 and 2 are connected
2,3
2,5
4,2
5,11
11,12
6,7
5,6
3,6
6,8
8,10
8,9

1'den 7'ye kadar gelen yolları bulun:

Cevap: 2 yolları bulundu ve bunlar

1,2,3,6,7
1,2,5,6,7

alt

Bulunan uygulama burada aynı kullanacağım güzel

İşte piton yukarıdaki bağlantıdan snippet'idir

# a sample graph
graph = {'A': ['B', 'C','E'],
             'B': ['A','C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F','D'],
             'F': ['C']}

class MyQUEUE: # just an implementation of a queue

    def __init__(self):
        self.holder = []

    def enqueue(self,val):
        self.holder.append(val)

    def dequeue(self):
        val = None
        try:
            val = self.holder[0]
            if len(self.holder) == 1:
                self.holder = []
            else:
                self.holder = self.holder[1:]   
        except:
            pass

        return val  

    def IsEmpty(self):
        result = False
        if len(self.holder) == 0:
            result = True
        return result


path_queue = MyQUEUE() # now we make a queue


def BFS(graph,start,end,q):

    temp_path = [start]

    q.enqueue(temp_path)

    while q.IsEmpty() == False:
        tmp_path = q.dequeue()
        last_node = tmp_path[len(tmp_path)-1]
        print tmp_path
        if last_node == end:
            print VALID_PATH : ,tmp_path
        for link_node in graph[last_node]:
            if link_node not in tmp_path:
                #new_path = []
                new_path = tmp_path + [link_node]
                q.enqueue(new_path)

BFS(graph,A,D,path_queue)

-------------results-------------------
['A']
['A', 'B']
['A', 'C']
['A', 'E']
['A', 'B', 'C']
['A', 'B', 'D']
VALID_PATH :  ['A', 'B', 'D']
['A', 'C', 'D']
VALID_PATH :  ['A', 'C', 'D']
['A', 'E', 'F']
['A', 'E', 'D']
VALID_PATH :  ['A', 'E', 'D']
['A', 'B', 'C', 'D']
VALID_PATH :  ['A', 'B', 'C', 'D']
['A', 'E', 'F', 'C']
['A', 'E', 'F', 'C', 'D']
VALID_PATH :  ['A', 'E', 'F', 'C', 'D']
Oluştur 03/04/2009 saat 12:09
kaynak kullanıcı
Diğer dillerde...                            


8 cevaplar

oy
-3

Ne yapmaya çalıştığını kontrol bir (yönlendirilmiş?) Grafikte iki köşe arasında bir yol bulmak için esas olan Dijkstra'nın algoritması size en kısa yolu gerekir ya da yolları var ne gerekiyorsa basit özyinelemeli fonksiyon yazarsanız.

Cevap 03/04/2009 saat 12:14
kaynak kullanıcı

oy
33

Enine Arama bir grafiğini bir yandan öbür ve aslında, bir başlangıç düğümden tüm yolları bulur. Genellikle BFS Ancak bütün yolları tutmaz. Bunun yerine, kısa yolu kaydetmek için bir prededecessor fonksiyonu tt günceller. Böylece kolayca algoritmayı değiştirebilir π(n)sadece saklamaz bir öncülü ancak olası seleflerinin bir listesini.

Sonra tüm olası yolları bu işlevde kodlanmış ve yinelemeli olası tüm yol kombinasyonlarını elde tt geçerek edilir.

Bu notasyonu kullanan biri iyi yalancı kod bulunabilir Algoritmalara Giriş Cormen tarafından vd. ve sonradan konuyla ilgili birçok Üniversite komut kullanılmıştır. “BFS pseudocode öncel π” için bir Google araması uproots Stack Exchange'de bu hit .

Cevap 03/04/2009 saat 12:38
kaynak kullanıcı

oy
1

Tüm yolları istiyorsanız Özyinelemeyi kullanın.

bir bitişiklik listesini kullanarak, tercihen, ziyaret edilen köşe geçerli listesi doldurmak için çalışan bir fonksiyon f () oluşturur. böylece gibi:

void allPaths(vector<int> previous, int current, int destination)
{
    previous.push_back(current);

    if (current == destination)
        //output all elements of previous, and return

    for (int i = 0; i < neighbors[current].size(); i++)
        allPaths(previous, neighbors[current][i], destination);
}

int main()
{
    //...input
    allPaths(vector<int>(), start, end);
}

Nedeniyle vektör değer geçirilir gerçeği (ve dolayısıyla yinelemeli prosedürü daha aşağı yapılan değişiklikler kalıcı değildir) için, mümkün olan tüm kombinasyonlar numaralandırılır.

Sen geçirerek verimliliği biraz kazanabilir önceki (ve dolayısıyla tekrar tekrar vektörü kopyalamak gerek yok) referans olarak vektör ancak işler manuel) (popped_back olsun emin olmak gerekir.

Bir şey daha: grafik döngüleri varsa, bu çalışmayacaktır. (Hepinizin bulmak istersiniz bu durumda farz basit içine bir şey eklemeden önce, sonra yolları) önceki , zaten var ilk onay eğer orada vektör.

Eğer tüm istiyorsanız en kısa yolları, bu algoritma ile Konrad'ın öneriyi kullanabilirsiniz.

Cevap 03/04/2009 saat 12:45
kaynak kullanıcı

oy
7

Dijkstra'nın algoritması ağırlıklı yollara daha geçerlidir ve afiş, bütün yolları bulmak için değil sadece kısa isteyen oldu gibi geliyor.

Bu uygulama için, ben ve favori arama yöntemi kullanmak bir grafik (o yönlendirilmesi gerek olmaz gibi uygulama geliyor) inşa ediyorum. Hepinizin yolları değil, sadece bir tahmin kısadadır tane istiyorum gibi geliyor, bu yüzden seçtiğiniz basit özyinelemeli algoritma kullanıyoruz.

Grafik, siklik olabilir, bu tek bir sorundur.

bağlantılarıyla:

  • 1, 2
  • 1, 3
  • 2, 3
  • 2, 4

> 2 - -> 3 -> 1 1-> 4 bir yolu ararken, 1 olarak döngüsünü olabilir.

Bu durumda, o zaman düğümleri geçme gibi bir yığın tutardım. İşte o grafiğin ve (biçimlendirme için üzgün - hayır tablo isteğe bağlı) çıkan yığın için adımlarla listesi aşağıda verilmiştir:

Düğüm (mümkün olan bir sonraki düğüm eksi biz geldiği yerde) [yığın]

  1. 1 (2, 3) [1]
  2. 2 (3, 4) [1, 2]
  3. 3 (1) [1, 2, 3]
  4. 1 (2, 3) [1, 2, 3, 1] // hata - yığın numarasını yinelenen - döngüsü tespit
  5. 3 () [1, 2, 3] üç düğüm basamaklı arka ve yığın kapalı 1 attı //. Artık düğümler buradan keşfetmek
  6. 2 (4): [1, 2] düğüm 2 arka basamaklı ve yığın kapalı 1 attı //.
  7. 4 () [1, 2, 4] bulunan // Hedef düğüm - bir yol için kayıt yığını. Artık düğümler buradan keşfetmek
  8. 2 () [1, 2] düğüm 2 arka basamaklı ve yığın kapalı 4 attı //. Artık düğümler buradan keşfetmek
  9. 1 (3): [1] düğüm 1'e geri basamaklı ve yığın kapalı 2 attı //.
  10. 3 (2): [1, 3]
  11. 2 (1, 4) [1, 3, 2]
  12. 1 (2, 3) [1, 3, 2, 1] // hata - yığın numarasını yinelenen - döngüsü tespit
  13. 2 (4): [1, 3, 2] düğüm 2-basamaklı ve geri // yığın kapalı 1 attı
  14. 4 () [1, 3, 2, 4] bulunan hedef düğüm - bir yol için kayıt yığını. Artık düğümler buradan keşfetmek
  15. 2 () [1, 3, 2] düğüm 2 arka basamaklı ve yığın kapalı 4 attı //. Artık düğümler
  16. 3 () [1, 3] düğüm 3'e geri basamaklı ve yığın kapalı 2 attı //. Artık düğümler
  17. 1 () [1] düğüm 1'e geri basamaklı ve yığın kapalı 3 attı //. Artık düğümler
  18. 2 kaydedilen yolları ile yapılan [1, 2, 4] ve [1, 3, 2, 4]
Cevap 03/04/2009 saat 12:52
kaynak kullanıcı

oy
3

Orijinal kod biraz hantal ve size bir yol grafiği üzerinde 2 nokta arasındaki varsa bulmak için BFS'ye kullanmak istiyorsanız bunun yerine collections.deque kullanmak isteyebilirsiniz. Benım kesmek hızlı bir çözümdür:

Not: İki düğüm arasındaki hiçbir yolu yoktur varsa bu yöntem sonsuz devam edebilir. Ben YMMV, bütün davaları test etmedim.

from collections import deque

# a sample graph
  graph = {'A': ['B', 'C','E'],
           'B': ['A','C', 'D'],
           'C': ['D'],
           'D': ['C'],
           'E': ['F','D'],
           'F': ['C']}

   def BFS(start, end):
    """ Method to determine if a pair of vertices are connected using BFS

    Args:
      start, end: vertices for the traversal.

    Returns:
      [start, v1, v2, ... end]
    """
    path = []
    q = deque()
    q.append(start)
    while len(q):
      tmp_vertex = q.popleft()
      if tmp_vertex not in path:
        path.append(tmp_vertex)

      if tmp_vertex == end:
        return path

      for vertex in graph[tmp_vertex]:
        if vertex not in path:
          q.append(vertex)
Cevap 20/07/2009 saat 03:22
kaynak kullanıcı

oy
22

PYTHON uzmanı, C aynı kod olmayanlar için ++

//@Author :Ritesh Kumar Gupta
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
vector<vector<int> >GRAPH(100);
inline void print_path(vector<int>path)
{
    cout<<"[ ";
    for(int i=0;i<path.size();++i)
    {
        cout<<path[i]<<" ";
    }
    cout<<"]"<<endl;
}
bool isadjacency_node_not_present_in_current_path(int node,vector<int>path)
{
    for(int i=0;i<path.size();++i)
    {
        if(path[i]==node)
        return false;
    }
    return true;
}
int findpaths(int source ,int target ,int totalnode,int totaledge )
{
    vector<int>path;
    path.push_back(source);
    queue<vector<int> >q;
    q.push(path);

    while(!q.empty())
    {
        path=q.front();
        q.pop();

        int last_nodeof_path=path[path.size()-1];
        if(last_nodeof_path==target)
        {
            cout<<"The Required path is:: ";
            print_path(path);
        }
        else
        {
            print_path(path);
        }

        for(int i=0;i<GRAPH[last_nodeof_path].size();++i)
        {
            if(isadjacency_node_not_present_in_current_path(GRAPH[last_nodeof_path][i],path))
            {

                vector<int>new_path(path.begin(),path.end());
                new_path.push_back(GRAPH[last_nodeof_path][i]);
                q.push(new_path);
            }
        }




    }
    return 1;
}
int main()
{
    //freopen("out.txt","w",stdout);
    int T,N,M,u,v,source,target;
    scanf("%d",&T);
    while(T--)
    {
        printf("Enter Total Nodes & Total Edges\n");
        scanf("%d%d",&N,&M);
        for(int i=1;i<=M;++i)
        {
            scanf("%d%d",&u,&v);
            GRAPH[u].push_back(v);
        }
        printf("(Source, target)\n");
        scanf("%d%d",&source,&target);
        findpaths(source,target,N,M);
    }
    //system("pause");
    return 0;
}

/*
Input::
1
6 11
1 2 
1 3
1 5
2 1
2 3
2 4
3 4
4 3
5 6
5 4
6 3
1 4

output:
[ 1 ]
[ 1 2 ]
[ 1 3 ]
[ 1 5 ]
[ 1 2 3 ]
The Required path is:: [ 1 2 4 ]
The Required path is:: [ 1 3 4 ]
[ 1 5 6 ]
The Required path is:: [ 1 5 4 ]
The Required path is:: [ 1 2 3 4 ]
[ 1 2 4 3 ]
[ 1 5 6 3 ]
[ 1 5 4 3 ]
The Required path is:: [ 1 5 6 3 4 ]


*/
Cevap 04/06/2012 saat 20:17
kaynak kullanıcı

oy
2

bitişiklik matrisi verilebilir:

{0, 1, 3, 4, 0, 0}

{0, 0, 2, 1, 2, 0}

{0, 1, 0, 3, 0, 0}

{0, 1, 1, 0, 0, 1}

{0, 0, 0, 0, 0, 6}

{0, 1, 0, 1, 0, 0}

Aşağıdaki Wolfram Mathematica kodu bir grafik, iki düğüm arasındaki basit yolu bulmak sorunu çözer. Ben döngüleri takip etmek ve istenilen çıktıyı saklamak için basit özyinelemeye ve iki küresel var kullanılabilir. kod sadece kod anlaşılır olması için optimize edilmemiştir. "Baskı" nasıl çalıştığını açıklamak yararlı olacaktır.

cycleQ[l_]:=If[Length[DeleteDuplicates[l]] == Length[l], False, True];
getNode[matrix_, node_]:=Complement[Range[Length[matrix]],Flatten[Position[matrix`node`, 0]]];

builtTree[node_, matrix_]:=Block[{nodes, posAndNodes, root, pos},
    If[{node} != {} && node != endNode ,
        root = node;
        nodes = getNode[matrix, node];
        (*Print["root:",root,"---nodes:",nodes];*)

        AppendTo[lcycle, Flatten[{root, nodes}]];
        If[cycleQ[lcycle] == True,
            lcycle = Most[lcycle]; appendToTree[root, nodes];,
            Print["paths: ", tree, "\n", "root:", root, "---nodes:",nodes];
            appendToTree[root, nodes];

        ];
    ];

appendToTree[root_, nodes_] := Block[{pos, toAdd},
    pos = Flatten[Position[tree[[All, -1]], root]];
    For[i = 1, i <= Length[pos], i++,
        toAdd = Flatten[Thread[{tree[[pos`i`]], {#}}]] & /@ nodes;
        (* check cycles!*)            
        If[cycleQ[#] != True, AppendTo[tree, #]] & /@ toAdd;
    ];
    tree = Delete[tree, {#} & /@ pos];
    builtTree[#, matrix] & /@ Union[tree[[All, -1]]];
    ];
];

kodu aramak için: initNode = 1; endNode = 6; lcycle = {}; ağaç = `initNode`; builtTree [initNode matris];

yollar: `1 'kökü: 1 --- düğümleri: {2,3,4}

yollar: {{1,2}, {1,3}, {1,4}} kökü: 2 --- düğümleri: {3,4,5}

yollar: {{1,3}, {1,4}, {1,2,3}, {1,2,4}, {1,2,5}} kökü: 3 --- düğümleri: {2, 4}

yollar: {{1,4}, {1,2,4}, {1,2,5}, {1,3,4}, {1,2,3,4}, {1,3,2, 4}, {1,3,2,5}} kökü: 4 --- düğümleri: {2,3,6}

yollar: {{1,2,5}, {1,3,2,5}, {1,4,6}, {1,2,4,6}, {1,3,4,6}, { 1,2,3,4,6}, {1,3,2,4,6}, {1,4,2,5}, {1,3,4,2,5}, {1,4, 3,2,5}} kökü: 5 --- düğümleri: {6}

Bulgular: {{1, 4, 6}, {1, 2, 4, 6}, {1, 2, 5, 6} {1, 3, 4, 6}, {1, 2, 3, 4, 6}, {1, 3, 2, 4, 6} {1, 3, 2, 5, 6}, {1, 4, 2, 5, 6} {1, 3, 4, 2, 5, 6}, {1, 4, 3, 2, 5, 6}}

... Ne yazık ki daha iyi bir şekilde sonuçları göstermek için resim yüklemek olamaz :(

http://textanddatamining.blogspot.com

Cevap 23/08/2012 saat 19:58
kaynak kullanıcı

oy
3

Prolog olarak (özellikle, SWI-Prolog)

:- use_module(library(tabling)).

% path(+Graph,?Source,?Target,?Path)
:- table path/4.

path(_,N,N,[N]).
path(G,S,T,[S|Path]) :-
    dif(S,T),
    member(S-I, G), % directed graph
    path(G,I,T,Path).

Ölçek:

paths :- Graph =
    [ 1- 2  % node 1 and 2 are connected
    , 2- 3 
    , 2- 5 
    , 4- 2 
    , 5-11
    ,11-12
    , 6- 7 
    , 5- 6 
    , 3- 6 
    , 6- 8 
    , 8-10
    , 8- 9
    ],
    findall(Path, path(Graph,1,7,Path), Paths),
    maplist(writeln, Paths).

?- paths.
[1,2,3,6,7]
[1,2,5,6,7]
true.
Cevap 15/09/2016 saat 12:02
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more