Keresse meg a pályák két adott csomópont?

szavazat
42

Mondjuk én csomópont csatlakozik az alábbi módon, hogyan érkezik meg a számát utak között fennálló adott pont és az elérési út részleteit?

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

Találja meg az utak 1-7:

Válasz: 2 utakat találni, és azok

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

alt

végrehajtás talált itt is szép fogom használni ugyanazt

Itt látható a részletet a fenti linkre python

# 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']
A kérdést 03/04/2009 12:09
a forrás felhasználó
Más nyelveken...                            


8 válasz

szavazat
-3

Mit akar csinálni lényegében az, hogy megtalálja az utat két csúcs között egy (irányított?) Gráf nézd meg Dijkstra-algoritmus , ha szüksége van a legrövidebb út, vagy írj egy egyszerű rekurzív függvény, ha szüksége van bármilyen útvonalak vannak.

Válaszolt 03/04/2009 12:14
a forrás felhasználó

szavazat
33

Szélességi kereső bejárja a grafikonon, és valójában úgy találja, minden út egy kiindulási csomópont. Általában BFS nem tartja meg magának utat, de. Ehelyett, akkor frissíti a prededecessor függvény π menteni a legrövidebb utat. Könnyedén módosíthatja az algoritmus, hogy π(n)nem csak tárolja az egyik elődje, de egy listát a lehetséges elődei.

Ezután az összes lehetséges útvonalat vannak kódolva ezt a funkciót, és a mozgással rc rekurzív kap minden lehetséges út kombináció.

Egy jó pszeudokód, amely felhasználja ezt a jelölést megtalálható Bevezetés a Algoritmusok által Cormen et al. és ezt követően használják számos egyetem szkriptek a témában. A Google-keresés „BFS pszeudokódokra elődje π” gyökerestől ez hit Stack Exchange .

Válaszolt 03/04/2009 12:38
a forrás felhasználó

szavazat
1

Ha azt akarjuk, hogy utak, használja a rekurziót.

Használata egy szomszédsági lista, előnyösen, hozzon létre egy f (), amely megkísérli, hogy töltse ki egy aktuális listáját látogatott csúcsok. Így:

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);
}

Annak a ténynek köszönhetően, hogy a vektor által elfogadott érték (és ezáltal végrehajtott változtatásokat lejjebb a rekurzív eljárásban nem állandó), az összes lehetséges kombinációt felsorolt.

Akkor kapnak egy kis hatékonyság átadásával a korábbi vektor hivatkozással (és így hogy nem kell másolni a vektor újra és újra), de akkor is meg kell győződnie arról, hogy a dolgok popped_back () kézzel.

Még egy dolog: ha a gráf ciklus, ez nem fog működni. (Feltételezem, ebben az esetben akkor szeretné megtalálni az összes egyszerű utak, akkor) hozzáadása előtt valamit a korábbi vektor, először ellenőrizze, ha már ott van.

Ha minden legrövidebb utat használja Konrad javaslata ezzel algoritmus.

Válaszolt 03/04/2009 12:45
a forrás felhasználó

szavazat
7

Dijkstra algoritmus inkább érvényes súlyozott utak és úgy hangzik, mint a plakát akarnak találni az összes utakat, nem csak a legrövidebb.

Ehhez az alkalmazáshoz, én építeni egy grafikon (az alkalmazás úgy hangzik, mint ez nem kell irányítani), és használhatja a kedvenc keresési módszert. Úgy hangzik, mint azt szeretnénk minden út, nem csak egy tipp a legrövidebb, így egy egyszerű rekurzív algoritmus, amelyet választott.

Az egyetlen probléma ezzel az, ha a gráf lehet ciklikus.

A csatlakozások:

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

Miközben keresi a pálya 1-> 4, akkor lehetett volna a ciklus 1 -> 2 -> 3 -> 1.

Ebben az esetben, akkor azt tartsa egy halom mint áthaladó csomópontokat. Itt egy lista a lépéseket, hogy a grafikonon, és az így kapott köteg (bocs a formázás - nincs tábla opció):

aktuális csomópont (lehetséges következő csomópontok mínusz honnan jöttünk) [verem]

  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] // hiba - ismétlődő számot a verem - ciklus észlelt
  5. 3 () [1, 2, 3] // vissza-lépcsős csomóponthoz három és beugrott, 1 ki a köteg. Nincs több csomópontot, hogy vizsgálja meg innen
  6. 2 (4) [1, 2] // vissza-lépcsős 2 csomópontra és beugrott, 1 ki a köteg.
  7. 4 () [1, 2, 4] // cél csomópont megtalált - rekordot verem egy utat. Nincs több csomópontot, hogy vizsgálja meg innen
  8. 2 () [1, 2] // vissza-lépcsős 2 csomópontra és beugrott 4 ki a köteg. Nincs több csomópontot, hogy vizsgálja meg innen
  9. 1 (3) [1] // vissza-lépett 1 csomópont és a pattogatott 2 le a verem.
  10. 3 (2) [1, 3]
  11. 2 (1, 4) [1, 3, 2]
  12. 1 (2, 3) [1, 3, 2, 1] // hiba - ismétlődő számot a verem - ciklus észlelt
  13. 2 (4) [1, 3, 2] // vissza-lépcsős 2 csomópontra és beugrott 1 ki a köteg
  14. 4 () [1, 3, 2, 4] cél csomópont megtalált - rekordot verem egy utat. Nincs több csomópontot, hogy vizsgálja meg innen
  15. 2 () [1, 3, 2] // vissza-lépcsős 2 csomópontra és beugrott 4 ki a köteg. Nincs több csomópont
  16. 3 () [1, 3] // vissza-lépett 3 csomópont és beugrott 2 le a verem. Nincs több csomópont
  17. 1 () [1] // vissza-lépett 1 csomópont és a pattogatott 3 ki a köteget. Nincs több csomópont
  18. Kész 2 rögzített utak a [1, 2, 4] és [1, 3, 2, 4]
Válaszolt 03/04/2009 12:52
a forrás felhasználó

szavazat
3

Az eredeti kód egy kicsit nehézkes, és érdemes használni a collections.deque helyett, ha a használni kívánt BFS megtalálni, ha egy útvonal létezik a 2 pont a grafikonon. Itt van egy gyors megoldás Betörtem fel:

Megjegyzés: ez a módszer lehet a végtelenségig folytatódhat, ha nem létezik út között a két csomópont. Én még nem tesztelték minden esetben YMMV.

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)
Válaszolt 20/07/2009 03:22
a forrás felhasználó

szavazat
22

Azok számára, akik nem PYTHON szakértő, ugyanazt a kódot C ++

//@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 ]


*/
Válaszolt 04/06/2012 20:17
a forrás felhasználó

szavazat
2

mivel a szomszédsági mátrix:

{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 következő Wolfram Mathematica kód oldja meg a problémát, hogy megtalálja az összes egyszerű útvonalak két csomópont között egy grafikonon. Régebben egyszerű rekurzív, és két globális var nyomon követni a ciklusok és tárolja el a kívánt kimenetet. A kód nem lett optimalizálva kedvéért kód világosság. A „print” hasznos lehet, hogy tisztázza, hogyan működik.

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]]];
    ];
];

hívni a kód: initNode = 1; végpontja = 6; lcycle = {}; fa = `initNode`; builtTree [initNode, mátrix];

utak: `1` gyökér: 1 --- csomópontok: {2,3,4}

utak: {{1,2}, {1,3}, {1,4}} gyökér: 2 --- csomópontok: {3,4,5}

utak: {{1,3}, {1,4}, {1,2,3}, {1,2,4}, {1,2,5}} gyökér: 3 --- csomópontok: {2, 4}

utak: {{1,4}, {1,2,4}, {1,2,5}, {1,3,4}, {1,2,3,4}, {1,3,2, 4}, {1,3,2,5}} gyökér: 4 --- csomópontok: {2,3,6}

utak: {{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}} gyökér: 5 --- csomópontok: {6}

EREDMÉNYEK: {{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}}

... Sajnos nem tudok feltölteni képeket mutatni az eredményeket egy jobb út :(

http://textanddatamining.blogspot.com

Válaszolt 23/08/2012 19:58
a forrás felhasználó

szavazat
3

Prologban (specifikusan, 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).

teszt:

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.
Válaszolt 15/09/2016 12:02
a forrás felhasználó

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