Hierholzers algoritme for rettet graf

Hierholzers algoritme for rettet graf

Gitt en rettet Eulersk graf er oppgaven å skrive ut en Euler krets . En Euler-krets er en bane som krysser hver kant av en graf nøyaktig én gang, og banen ender på startpunktet.

Note: Den gitte grafen inneholder en Euler-krets.

Eksempel:



Inngang : Rettet graf

Hierholzers algoritme for rettet graf

Produksjon: 0 3 4 0 2 1 0

Forutsetninger:

  • Vi har diskutert problem med å finne ut om en gitt graf er Eulerian eller ikke for en urettet graf
  • Betingelser for Eulerisk krets i en rettet Grpag: (1) Alle toppunkter tilhører en enkelt sterkt tilkoblet komponent. (2) Alle toppunkter har samme inn-grad og ut-grad. Merk at for en urettet graf er betingelsen forskjellig (alle toppunkter har jevn grad)

Nærme:

  1. Velg et hvilket som helst startpunkt v og følg et spor av kanter fra det toppunktet til du går tilbake til v. Det er ikke mulig å bli sittende fast ved noe annet toppunkt enn v fordi indegree og outdegree for hvert toppunkt må være det samme når stien går inn i et annet toppunkt w det må være en ubrukt kant som forlater w. Turen dannet på denne måten er en lukket tur, men dekker kanskje ikke alle toppunktene og kantene på den første grafen.
  2. Så lenge det eksisterer et toppunkt u som tilhører den nåværende turen, men som har tilstøtende kanter som ikke er en del av turen, starter du en annen sti fra u følger ubrukte kanter til du går tilbake til u og blir med på turen dannet på denne måten til forrige tur.

Illustrasjon:

Ta eksempel på grafen ovenfor med 5 noder: adj = {{2 3} {0} {1} {4} {0}}.

  1. Start ved toppunktet 0 :
    • Gjeldende bane: [0]
    • Krets: []
  2. Toppunkt 0 → 3 :
    • Nåværende bane: [0 3]
    • Krets: []
  3. Toppunkt 3 → 4 :
    • Nåværende bane: [0 3 4]
    • Krets: []
  4. Toppunkt 4 → 0 :
    • Nåværende bane: [0 3 4 0]
    • Krets: []
  5. Toppunkt 0 → 2 :
    • Nåværende bane: [0 3 4 0 2]
    • Krets: []
  6. Toppunkt 2 → 1 :
    • Gjeldende bane: [0 3 4 0 2 1]
    • Krets: []
  7. Toppunkt 1 → 0 :
    • Gjeldende bane: [0 3 4 0 2 1 0]
    • Krets: []
  8. Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
    • Gjeldende bane: [0 3 4 0 2 1]
    • Krets: [0]
  9. Gå tilbake til toppunkt 1 : Legg til 1 til kretsen.
    • Nåværende bane: [0 3 4 0 2]
    • Krets: [0 1]
  10. Gå tilbake til toppunkt 2 : Legg til 2 til kretsen.
    • Nåværende bane: [0 3 4 0]
    • Krets: [0 1 2]
  11. Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
    • Nåværende bane: [0 3 4]
    • Krets: [0 1 2 0]
  12. Gå tilbake til toppunkt 4 : Legg til 4 til kretsen.
    • Nåværende bane: [0 3]
    • Krets: [0 1 2 0 4]
  13. Gå tilbake til toppunkt 3 : Legg til 3 til kretsen.
    • Gjeldende bane: [0]
    • Krets: [0 1 2 0 4 3]
  14. Gå tilbake til toppunkt 0 : Legg til 0 til kretsen.
    • Gjeldende bane: []
    • Krets: [0 1 2 0 4 3 0]

Nedenfor er implementeringen for tilnærmingen ovenfor: 

C++
   // C++ program to print Eulerian circuit in given   // directed graph using Hierholzer algorithm   #include          using     namespace     std  ;   // Function to print Eulerian circuit   vector   <  int  >     printCircuit  (  vector   <  vector   <  int  >>     &  adj  )     {      int     n     =     adj  .  size  ();      if     (  n     ==     0  )      return     {};      // Maintain a stack to keep vertices      // We can start from any vertex here we start with 0      vector   <  int  >     currPath  ;      currPath  .  push_back  (  0  );      // list to store final circuit      vector   <  int  >     circuit  ;      while     (  currPath  .  size  ()     >     0  )     {      int     currNode     =     currPath  [  currPath  .  size  ()     -     1  ];      // If there's remaining edge in adjacency list      // of the current vertex      if     (  adj  [  currNode  ].  size  ()     >     0  )     {          // Find and remove the next vertex that is      // adjacent to the current vertex      int     nextNode     =     adj  [  currNode  ].  back  ();      adj  [  currNode  ].  pop_back  ();      // Push the new vertex to the stack      currPath  .  push_back  (  nextNode  );      }      // back-track to find remaining circuit      else     {      // Remove the current vertex and      // put it in the circuit      circuit  .  push_back  (  currPath  .  back  ());      currPath  .  pop_back  ();      }      }      // reverse the result vector       reverse  (  circuit  .  begin  ()     circuit  .  end  ());          return     circuit  ;   }   int     main  ()     {      vector   <  vector   <  int  >>     adj     =     {{  2       3  }     {  0  }     {  1  }     {  4  }     {  0  }};      vector   <  int  >     ans     =     printCircuit  (  adj  );          for     (  auto     v  :     ans  )     cout      < <     v      < <     ' '  ;      cout      < <     endl  ;      return     0  ;   }   
Java
   // Java program to print Eulerian circuit in given   // directed graph using Hierholzer algorithm   import     java.util.*  ;   class   GfG     {      // Function to print Eulerian circuit      static     List   <  Integer  >     printCircuit  (  List   <  List   <  Integer  >>     adj  )     {      int     n     =     adj  .  size  ();      if     (  n     ==     0  )      return     new     ArrayList   <>  ();      // Maintain a stack to keep vertices      // We can start from any vertex here we start with 0      List   <  Integer  >     currPath     =     new     ArrayList   <>  ();      currPath  .  add  (  0  );      // list to store final circuit      List   <  Integer  >     circuit     =     new     ArrayList   <>  ();      while     (  currPath  .  size  ()     >     0  )     {      int     currNode     =     currPath  .  get  (  currPath  .  size  ()     -     1  );      // If there's remaining edge in adjacency list      // of the current vertex      if     (  adj  .  get  (  currNode  ).  size  ()     >     0  )     {      // Find and remove the next vertex that is      // adjacent to the current vertex      int     nextNode     =     adj  .  get  (  currNode  ).  get  (  adj  .  get  (  currNode  ).  size  ()     -     1  );      adj  .  get  (  currNode  ).  remove  (  adj  .  get  (  currNode  ).  size  ()     -     1  );      // Push the new vertex to the stack      currPath  .  add  (  nextNode  );      }      // back-track to find remaining circuit      else     {      // Remove the current vertex and      // put it in the circuit      circuit  .  add  (  currPath  .  get  (  currPath  .  size  ()     -     1  ));      currPath  .  remove  (  currPath  .  size  ()     -     1  );      }      }      // reverse the result vector      Collections  .  reverse  (  circuit  );      return     circuit  ;      }      public     static     void     main  (  String  []     args  )     {      List   <  List   <  Integer  >>     adj     =     new     ArrayList   <>  ();      adj  .  add  (  new     ArrayList   <>  (  Arrays  .  asList  (  2       3  )));      adj  .  add  (  new     ArrayList   <>  (  Arrays  .  asList  (  0  )));         adj  .  add  (  new     ArrayList   <>  (  Arrays  .  asList  (  1  )));         adj  .  add  (  new     ArrayList   <>  (  Arrays  .  asList  (  4  )));         adj  .  add  (  new     ArrayList   <>  (  Arrays  .  asList  (  0  )));         List   <  Integer  >     ans     =     printCircuit  (  adj  );      for     (  int     v     :     ans  )     System  .  out  .  print  (  v     +     ' '  );      System  .  out  .  println  ();      }   }   
Python
   # Python program to print Eulerian circuit in given   # directed graph using Hierholzer algorithm   # Function to print Eulerian circuit   def   printCircuit  (  adj  ):   n   =   len  (  adj  )   if   n   ==   0  :   return   []   # Maintain a stack to keep vertices   # We can start from any vertex here we start with 0   currPath   =   [  0  ]   # list to store final circuit   circuit   =   []   while   len  (  currPath  )   >   0  :   currNode   =   currPath  [  -  1  ]   # If there's remaining edge in adjacency list   # of the current vertex   if   len  (  adj  [  currNode  ])   >   0  :   # Find and remove the next vertex that is   # adjacent to the current vertex   nextNode   =   adj  [  currNode  ]  .  pop  ()   # Push the new vertex to the stack   currPath  .  append  (  nextNode  )   # back-track to find remaining circuit   else  :   # Remove the current vertex and   # put it in the circuit   circuit  .  append  (  currPath  .  pop  ())   # reverse the result vector   circuit  .  reverse  ()   return   circuit   if   __name__   ==   '__main__'  :   adj   =   [[  2     3  ]   [  0  ]   [  1  ]   [  4  ]   [  0  ]]   ans   =   printCircuit  (  adj  )   for   v   in   ans  :   print  (  v     end  =  ' '  )   print  ()   
C#
   // C# program to print Eulerian circuit in given   // directed graph using Hierholzer algorithm   using     System  ;   using     System.Collections.Generic  ;   class     GfG     {          // Function to print Eulerian circuit      static     List   <  int  >     printCircuit  (  List   <  List   <  int  >>     adj  )     {      int     n     =     adj  .  Count  ;      if     (  n     ==     0  )      return     new     List   <  int  >  ();      // Maintain a stack to keep vertices      // We can start from any vertex here we start with 0      List   <  int  >     currPath     =     new     List   <  int  >     {     0     };      // list to store final circuit      List   <  int  >     circuit     =     new     List   <  int  >  ();      while     (  currPath  .  Count     >     0  )     {      int     currNode     =     currPath  [  currPath  .  Count     -     1  ];      // If there's remaining edge in adjacency list      // of the current vertex      if     (  adj  [  currNode  ].  Count     >     0  )     {      // Find and remove the next vertex that is      // adjacent to the current vertex      int     nextNode     =     adj  [  currNode  ][  adj  [  currNode  ].  Count     -     1  ];      adj  [  currNode  ].  RemoveAt  (  adj  [  currNode  ].  Count     -     1  );      // Push the new vertex to the stack      currPath  .  Add  (  nextNode  );      }      // back-track to find remaining circuit      else     {      // Remove the current vertex and      // put it in the circuit      circuit  .  Add  (  currPath  [  currPath  .  Count     -     1  ]);      currPath  .  RemoveAt  (  currPath  .  Count     -     1  );      }      }      // reverse the result vector      circuit  .  Reverse  ();      return     circuit  ;      }      static     void     Main  (  string  []     args  )     {      List   <  List   <  int  >>     adj     =     new     List   <  List   <  int  >>     {      new     List   <  int  >     {     2       3     }      new     List   <  int  >     {     0     }      new     List   <  int  >     {     1     }      new     List   <  int  >     {     4     }      new     List   <  int  >     {     0     }      };      List   <  int  >     ans     =     printCircuit  (  adj  );      foreach     (  int     v     in     ans  )     {      Console  .  Write  (  v     +     ' '  );      }      Console  .  WriteLine  ();      }   }   
JavaScript
   // JavaScript program to print Eulerian circuit in given   // directed graph using Hierholzer algorithm   // Function to print Eulerian circuit   function     printCircuit  (  adj  )     {      let     n     =     adj  .  length  ;      if     (  n     ===     0  )      return     [];      // Maintain a stack to keep vertices      // We can start from any vertex here we start with 0      let     currPath     =     [  0  ];      // list to store final circuit      let     circuit     =     [];      while     (  currPath  .  length     >     0  )     {      let     currNode     =     currPath  [  currPath  .  length     -     1  ];      // If there's remaining edge in adjacency list      // of the current vertex      if     (  adj  [  currNode  ].  length     >     0  )     {      // Find and remove the next vertex that is      // adjacent to the current vertex      let     nextNode     =     adj  [  currNode  ].  pop  ();      // Push the new vertex to the stack      currPath  .  push  (  nextNode  );      }      // back-track to find remaining circuit      else     {      // Remove the current vertex and      // put it in the circuit      circuit  .  push  (  currPath  .  pop  ());      }      }      // reverse the result vector      circuit  .  reverse  ();      return     circuit  ;   }   let     adj     =     [[  2       3  ]     [  0  ]     [  1  ]     [  4  ]     [  0  ]];   let     ans     =     printCircuit  (  adj  );   for     (  let     v     of     ans  )     {      console  .  log  (  v       ' '  );   }   

Produksjon
0 3 4 0 2 1 0  

Tidskompleksitet:  O(V + E) hvor V er antall toppunkter og E er antall kanter i grafen. Grunnen til dette er fordi algoritmen utfører et dybde-først-søk (DFS) og besøker hvert toppunkt og hver kant nøyaktig én gang. Så for hvert toppunkt tar det O(1) tid å besøke det, og for hver kant tar det O(1) tid å krysse det.

Romkompleksitet: O(V + E) som algoritmen bruker en stabel for å lagre gjeldende bane og en liste for å lagre den endelige kretsen. Maksimal størrelse på stabelen kan i verste fall være V + E, så plasskompleksiteten er O(V + E).

Lag quiz

Topp Artikler

Kategori

Interessante Artikler