दिए गए दो नोड्स के बीच रास्तों का पता लगाएं?

वोट
42

कैसे मैं रास्तों कि दिए गए बिंदुओं के बीच मौजूद हैं, और पथ विवरण की संख्या में आने कि मैं नीचे फैशन में जुड़े नोड्स है कहते हैं,?

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 से 7 से रास्तों का पता लगाएं:

उत्तर: 2 रास्तों मिल गया है और वे कर रहे हैं

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

वैकल्पिक

पाया कार्यान्वयन यहाँ अच्छा मैं एक ही उपयोग करने के लिए जा रहा हूँ है

यहाँ अजगर में ऊपर के लिंक से स्निपेट है

# 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']
03/04/2009 को 12:09
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


8 जवाब

वोट
-3

आपको क्या करने की कोशिश कर रहे हैं की जाँच एक (निर्देशित?) ग्राफ में दो कोने के बीच एक रास्ता खोजने के लिए अनिवार्य रूप से है डिज्कस्ट्रा एल्गोरिथ्म यदि आप कम से कम पथ की जरूरत है या एक सरल पुनरावर्ती क्रिया बारे में अगर आप की जरूरत है जो कुछ रास्तों मौजूद हैं।

03/04/2009 को 12:14
का स्रोत उपयोगकर्ता

वोट
33

चौड़ाई-पहले खोज एक ग्राफ को पार करता है और वास्तव में एक शुरू करने नोड से सभी रास्ते पाता है। आमतौर पर, BFS सभी रास्ते नहीं रखता, लेकिन। इसके बजाय, यह कम से कम पथ बचाने के लिए एक prededecessor समारोह π अद्यतन करता है। ताकि आप आसानी से एल्गोरिथ्म संशोधित कर सकते हैं π(n)केवल दुकान नहीं है एक पूर्ववर्ती लेकिन संभव पूर्ववर्तियों की एक सूची।

तब सभी संभव पथ से गुजरने रिकर्सिवली आप सभी संभावित पथ संयोजन मिल π द्वारा इस समारोह में encoded रहे हैं, और।

एक अच्छा स्यूडोकोड जो इस अंकन का उपयोग करता है में पाया जा सकता एल्गोरिथम का परिचय Cormen द्वारा एट अल। और बाद में विषय पर कई विश्वविद्यालय लिपियों में इस्तेमाल किया गया है। के लिए "BFS स्यूडोकोड पूर्ववर्ती π" एक Google खोज uproots स्टैक एक्सचेंज पर इस हिट

03/04/2009 को 12:38
का स्रोत उपयोगकर्ता

वोट
1

आप सभी रास्तों चाहते हैं, प्रत्यावर्तन का उपयोग करें।

एक निकटता सूची का उपयोग करना, अधिमानतः एक समारोह च () का दौरा किया कोने की वर्तमान सूची को भरने के लिए प्रयास करता है बनाएँ। इस तरह:

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

तथ्य यह है कि वेक्टर मूल्य द्वारा पारित कर दिया है (और इस प्रकार पुनरावर्ती प्रक्रिया में आगे नीचे किए गए बदलाव स्थायी नहीं हैं) के कारण, सभी संभव संयोजनों enumerated हैं।

आप पास करके दक्षता का एक सा प्राप्त कर सकते हैं पिछले संदर्भ द्वारा वेक्टर (और इस तरह फिर से अधिक से अधिक वेक्टर नकल करने की जरूरत नहीं है), लेकिन आप यह सुनिश्चित करें कि चीजें popped_back मिल () मैन्युअल रूप से बनाने के लिए होगा।

एक और बात: अगर ग्राफ चक्र है, इस काम नहीं करेगा। (मैं इस मामले आप सभी से ढूंढना चाहेंगे में मान सरल पथ, तो) में कुछ जोड़ने से पहले पिछले , पहले जांच लें कि वह पहले से है वहाँ में वेक्टर।

आप सभी चाहते हैं कम से कम पथ, इस एल्गोरिथ्म के साथ कोनराड के सुझाव का उपयोग करें।

03/04/2009 को 12:45
का स्रोत उपयोगकर्ता

वोट
7

डिज्कस्ट्रा एल्गोरिथ्म भारित रास्तों के लिए और अधिक लागू होता है और यह लग रहा है जैसे पोस्टर, न सिर्फ कम से कम सभी रास्ते खोजने के लिए इच्छुक था।

इस आवेदन के लिए, मैं का निर्माण चाहते हैं और अपने पसंदीदा खोज विधि का उपयोग एक ग्राफ (यह निर्देशित किया की जरूरत नहीं होगी की तरह अपने आवेदन लगता है)। ऐसा लगता है कि आप सभी रास्तों, बस नहीं एक अनुमान कम से कम से कम एक चाहते हैं, इसलिए अपनी पसंद का एक सरल पुनरावर्ती एल्गोरिदम का उपयोग करें।

इस के साथ ही समस्या है, तो ग्राफ चक्रीय हो सकता है।

कनेक्शन के साथ:

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

> 2 - -> 3 -> 1 जबकि 1-> 4 से एक रास्ता तलाश में है, तो आप 1 का एक चक्र हो सकता था।

उस मामले में, तो मैं नोड्स traversing के रूप में एक ढेर रखना चाहते हैं। यहाँ है कि ग्राफ और जिसके परिणामस्वरूप ढेर (स्वरूपण के लिए खेद है - कोई तालिका विकल्प) के लिए चरणों के साथ एक सूची है:

वर्तमान नोड (संभव अगले नोड्स शून्य से हम कहाँ से आया है) [ढेर]

  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] // त्रुटि - स्टैक पर नंबर नकल - चक्र का पता चला
  5. 3 () [1, 2, 3] तीन नोड के लिए वापस कदम रखा और ढेर बंद 1 पॉप //। कोई और अधिक नोड्स यहां से पता लगाने के लिए
  6. 2 (4) [1, 2] // नोड 2 के लिए वापस कदम रखा और ढेर बंद 1 पॉप।
  7. 4 () [1, 2, 4] // लक्ष्य नोड नहीं मिला - एक पथ के लिए रिकॉर्ड ढेर। कोई और अधिक नोड्स यहां से पता लगाने के लिए
  8. 2 () [1, 2] // नोड 2 के लिए वापस कदम रखा और ढेर बंद 4 पॉपअप। कोई और अधिक नोड्स यहां से पता लगाने के लिए
  9. 1 (3) [1] नोड 1 को वापस कदम रखा और ढेर बंद 2 पॉप //।
  10. 3 (2) [1, 3]
  11. 2 (1, 4) [1, 3, 2]
  12. 1 (2, 3) [1, 3, 2, 1] // त्रुटि - स्टैक पर नंबर नकल - चक्र का पता चला
  13. 2 (4) [1, 3, 2] नोड 2 के लिए वापस कदम रखा और // 1 ढेर बंद पॉपअप
  14. 4 () [1, 3, 2, 4] लक्ष्य नोड नहीं मिला - एक पथ के लिए रिकॉर्ड ढेर। कोई और अधिक नोड्स यहां से पता लगाने के लिए
  15. 2 () [1, 3, 2] // नोड 2 के लिए वापस कदम रखा और ढेर बंद 4 पॉपअप। कोई और अधिक नोड्स
  16. 3 () [1, 3] // नोड से 3 वापस कदम रखा और ढेर बंद 2 पॉप। कोई और अधिक नोड्स
  17. 1 () [1] नोड 1 को वापस कदम रखा और ढेर बंद 3 पॉप //। कोई और अधिक नोड्स
  18. के 2 दर्ज की गई रास्तों का काम हो गया [1, 2, 4] और [1, 3, 2, 4]
03/04/2009 को 12:52
का स्रोत उपयोगकर्ता

वोट
3

मूल कोड थोड़ा बोझिल है और आप इसके बजाय collections.deque उपयोग करने के लिए आप एक रास्ता ग्राफ पर 2 अंक के बीच मौजूद है, तो लगता है BFS उपयोग करना चाहते हैं चाहते हो सकता है। यहां एक त्वरित समाधान मैं काट दिया है:

नोट: अगर वहाँ दो नोड्स के बीच कोई रास्ता मौजूद है इस विधि असीम जारी रखने के लिए हो सकता है। मैं सभी मामलों का परीक्षण नहीं किया, 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)
20/07/2009 को 03:22
का स्रोत उपयोगकर्ता

वोट
22

जो लोग अजगर विशेषज्ञ, सी में एक ही कोड नहीं हैं ++

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


*/
04/06/2012 को 20:17
का स्रोत उपयोगकर्ता

वोट
2

निकटता मैट्रिक्स दिया:

{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}

निम्नलिखित Wolfram मेथेमेटिका कोड समस्या एक ग्राफ के दो नोड्स के बीच सब सरल पथ को खोजने के लिए हल। मैं चक्र का ट्रैक रखने के लिए और वांछित आउटपुट स्टोर करने के लिए सरल प्रत्यावर्तन, और दो वैश्विक वर का इस्तेमाल किया। कोड सिर्फ कोड स्पष्टता के लिए अनुकूलित नहीं किया गया है। "प्रिंट" स्पष्ट करने के लिए यह कैसे काम करता मददगार होना चाहिए।

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

कोड कॉल करने के लिए: initNode = 1; endNode = 6; lcycle = {}; पेड़ = `initNode`; builtTree [initNode, मैट्रिक्स];

पथ: `1` जड़: 1 --- नोड्स: {2,3,4}

पथ: {{1,2}, {1,3}, {1,4}} जड़: 2 --- नोड्स: {3,4,5}

पथ: {{1,3}, {1,4}, {1,2,3} {1,2,4} {1,2,5}} जड़: 3 --- नोड्स: {2, 4}

पथ: {{1,4}, {1,2,4} {1,2,5} {1,3,4} {1,2,3,4} {1,3,2, 4} {1,3,2,5}} जड़: 4 --- नोड्स: {2,3,6}

पथ: {{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}} जड़: 5 --- नोड्स: {6}

परिणाम: {{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}}

... दुर्भाग्य से मैं छवियों को अपलोड नहीं कर सकते हैं एक बेहतर तरीके से परिणाम दिखाने के लिए :(

http://textanddatamining.blogspot.com

23/08/2012 को 19:58
का स्रोत उपयोगकर्ता

वोट
3

Prolog में (विशेष रूप से, 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).

परीक्षा:

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.
15/09/2016 को 12:02
का स्रोत उपयोगकर्ता

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