logo

Eulerjeva pot in vezje za neusmerjen graf

Eulerjeva pot je pot v grafu, ki obišče vsak rob točno enkrat. Eulerjev krog je Eulerjeva pot, ki se začne in konča na istem vozlišču.

Euler1



Euler2

Euler3

Kako ugotoviti, ali je dani graf Eulerjev ali ne?



Problem je enak naslednjemu vprašanju. Ali je mogoče narisati dani graf, ne da bi dvignili svinčnik s papirja in ne da bi večkrat obrisali kateri koli rob.
Graf se imenuje Eulerjev, če ima Eulerjev cikel, in pol-Eulerjev, če ima Eulerjevo pot. Težava se zdi podobna Hamiltonovi poti, ki je NP popolna težava za splošni graf. Na srečo lahko v polinomskem času ugotovimo, ali ima dani graf Eulerjevo pot ali ne. Pravzaprav ga lahko najdemo v O(V+E) času.
Sledi nekaj zanimivih lastnosti neusmerjenih grafov z Eulerjevo potjo in ciklom. Te lastnosti lahko uporabimo, da ugotovimo, ali je graf Eulerjev ali ne.

Eulerjev cikel: Neusmerjeni graf ima Eulerjev cikel, če sta izpolnjena naslednja dva pogoja.

  1. Vsa oglišča z različno stopnjo so povezana. Ne zanimajo nas vozlišča z ničelno stopnjo, ker ne pripadajo Eulerjevemu ciklu ali poti (upoštevamo le vse robove).
  2. Vsa oglišča imajo sodo stopnjo.

Eulerjeva pot: Neusmerjeni graf ima Eulerjevo pot, če sta izpolnjena naslednja dva pogoja.



  1. Enako kot pogoj (a) za Eulerjev cikel.
  2. Če ima nič ali dve točki liho stopnjo, vsa druga oglišča pa sodo stopnjo. Upoštevajte, da v neusmerjenem grafu ni možno samo eno vozlišče z liho stopnjo (vsota vseh stopenj je v neusmerjenem grafu vedno soda)

Upoštevajte, da se graf brez robov šteje za Eulerjev, ker ni robov, ki bi jih morali prečkati.

Kako to deluje?
V Eulerjevi poti se vsakič, ko obiščemo vozlišče v, sprehodimo skozi dva neobiskana robova z eno končno točko kot v. Zato morajo imeti vsa srednja oglišča v Eulerjevi poti sodo stopnjo. Za Eulerjev cikel je lahko katero koli oglišče srednje oglišče, zato morajo imeti vsa oglišča sodo stopnjo.

levi spoj proti desnemu spoju
Priporočena praksa Eulerjevo vezje in pot Poskusite!

Izvedba:

C++




// A C++ program to check if a given graph is Eulerian or not> #include> #include> using> namespace> std;> // A class that represents an undirected graph> class> Graph> {> >int> V;>// No. of vertices> >list<>int>>*adj;>// A dynamic array of adjacency lists> public>:> >// Constructor and destructor> >Graph(>int> V) {>this>->V = V; adj =>new> list<>int>>[IN]; }> >~Graph() {>delete> [] adj; }>// To avoid memory leak> >// function to add an edge to graph> >void> addEdge(>int> v,>int> w);> >// Method to check if this graph is Eulerian or not> >int> isEulerian();> >// Method to check if all non-zero degree vertices are connected> >bool> isConnected();> >// Function to do DFS starting from v. Used in isConnected();> >void> DFSUtil(>int> v,>bool> visited[]);> };> void> Graph::addEdge(>int> v,>int> w)> {> >adj[v].push_back(w);> >adj[w].push_back(v);>// Note: the graph is undirected> }> void> Graph::DFSUtil(>int> v,>bool> visited[])> {> >// Mark the current node as visited and print it> >visited[v] =>true>;> >// Recur for all the vertices adjacent to this vertex> >list<>int>>::iterator i;> >for> (i = adj[v].begin(); i != adj[v].end(); ++i)> >if> (!visited[*i])> >DFSUtil(*i, visited);> }> // Method to check if all non-zero degree vertices are connected.> // It mainly does DFS traversal starting from> bool> Graph::isConnected()> {> >// Mark all the vertices as not visited> >bool> visited[V];> >int> i;> >for> (i = 0; i visited[i] = false; // Find a vertex with non-zero degree for (i = 0; i if (adj[i].size() != 0) break; // If there are no edges in the graph, return true if (i == V) return true; // Start DFS traversal from a vertex with non-zero degree DFSUtil(i, visited); // Check if all non-zero degree vertices are visited for (i = 0; i if (visited[i] == false && adj[i].size()>0) vrni false; vrni resnico; } /* Funkcija vrne eno od naslednjih vrednosti 0 --> Če graf ni Eulerjev 1 --> Če ima graf Eulerjevo pot (pol-Eulerjev) 2 --> Če ima graf Eulerjevo vezje (Eulerjevo) */ int Graph::isEulerian() { // Preveri, ali so vsa oglišča brez ničelne stopnje povezana, če (isConnected() == false) vrne 0; // Štetje vozlišč z liho stopnjo int odd = 0; for (int i = 0; i if (adj[i].size() & 1) odd++; // Če je štetje več kot 2, potem graf ni Eulerjev, če (odd> 2) vrne 0; // Če je liho štetje je 2, potem je eulerjevo štetje 0, potem je eulerjevo štetje nikoli nemogoče biti 1 za vrnitev neusmerjenega grafa 1 : 2; // Funkcija za izvajanje testnih primerov nična test(Graf &g) { int res = g.isEulerian(); if (res == 0) cout<< 'graph is not Eulerian '; else if (res == 1) cout << 'graph has a Euler path '; else cout << 'graph has a Euler cycle '; } // Driver program to test above function int main() { // Let us create and test graphs shown in above figures Graph g1(5); g1.addEdge(1, 0); g1.addEdge(0, 2); g1.addEdge(2, 1); g1.addEdge(0, 3); g1.addEdge(3, 4); test(g1); Graph g2(5); g2.addEdge(1, 0); g2.addEdge(0, 2); g2.addEdge(2, 1); g2.addEdge(0, 3); g2.addEdge(3, 4); g2.addEdge(4, 0); test(g2); Graph g3(5); g3.addEdge(1, 0); g3.addEdge(0, 2); g3.addEdge(2, 1); g3.addEdge(0, 3); g3.addEdge(3, 4); g3.addEdge(1, 3); test(g3); // Let us create a graph with 3 vertices // connected in the form of cycle Graph g4(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); test(g4); // Let us create a graph with all vertices // with zero degree Graph g5(3); test(g5); return 0; }>

>

>

pomenska napaka

Java




// A Java program to check if a given graph is Eulerian or not> import> java.io.*;> import> java.util.*;> import> java.util.LinkedList;> // This class represents an undirected graph using adjacency list> // representation> class> Graph> {> >private> int> V;>// No. of vertices> >// Array of lists for Adjacency List Representation> >private> LinkedList adj[];> >// Constructor> >Graph(>int> v)> >{> >V = v;> >adj =>new> LinkedList[v];> >for> (>int> i=>0>; i adj[i] = new LinkedList(); } //Function to add an edge into the graph void addEdge(int v, int w) { adj[v].add(w);// Add w to v's list. adj[w].add(v); //The graph is undirected } // A function used by DFS void DFSUtil(int v,boolean visited[]) { // Mark the current node as visited visited[v] = true; // Recur for all the vertices adjacent to this vertex Iterator i = adj[v].listIterator(); while (i.hasNext()) { int n = i.next(); if (!visited[n]) DFSUtil(n, visited); } } // Method to check if all non-zero degree vertices are // connected. It mainly does DFS traversal starting from boolean isConnected() { // Mark all the vertices as not visited boolean visited[] = new boolean[V]; int i; for (i = 0; i visited[i] = false; // Find a vertex with non-zero degree for (i = 0; i if (adj[i].size() != 0) break; // If there are no edges in the graph, return true if (i == V) return true; // Start DFS traversal from a vertex with non-zero degree DFSUtil(i, visited); // Check if all non-zero degree vertices are visited for (i = 0; i if (visited[i] == false && adj[i].size()>0) vrni false; vrni resnico; } /* Funkcija vrne eno od naslednjih vrednosti 0 --> Če graf ni Eulerjev 1 --> Če ima graf Eulerjevo pot (pol-Eulerjev) 2 --> Če ima graf Eulerjevo vezje (Eulerjevo) */ int isEulerian() { // Preveri, ali so vsa oglišča brez ničelne stopnje povezana, če (isConnected() == false) vrne 0; // Štetje vozlišč z liho stopnjo int odd = 0; for (int i = 0; i if (adj[i].size()%2!=0) odd++; // Če je število več kot 2, potem graf ni Eulerjev, če (odd> 2) vrne 0; / / Če je liho število 2, potem je liho število 0, potem je liho število nikoli ne more biti 1 za neusmerjeni graf. Funkcija za izvajanje testnih primerov void test() { int res = isEulerian(); if (res == 0) System.out.println('graph is not Eulerian'); else if (res == 1) System. out.println('graf ima Eulerjev cikel'); else System.out.println('graf ima Eulerjev cikel') // Metoda gonilnika public static void main(String args[]); / Ustvarimo in preizkusimo grafe, prikazane na zgornjih slikah Graph g1.addEdge(1, 0); g1.addEdge(2, 1); (0, 3); g1.addEdge (0, 2); Graph g2. addEdge(2, 3); g2.addEdge(4, 0); g3 = new Graph(5). .addEdge(1, 0); g3.addEdge(0, 2); g3.addEdge(2, 1); g3.addEdge(0, 3); g3.addEdge(3, 4); g3.addEdge(1, 3); g3.test(); // Ustvarimo graf s 3 vozlišči // povezanimi v obliki cikla Graph g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Ustvarimo graf z vsemi vozlišči // z ničelno stopinjo Graph g5 = new Graph(3); g5.test(); } } // To kodo je prispeval Aakash Hasija>

>

>

Python3

model tcp ip




# Python program to check if a given graph is Eulerian or not> #Complexity : O(V+E)> from> collections>import> defaultdict> # This class represents a undirected graph using adjacency list representation> class> Graph:> >def> __init__(>self>, vertices):> >self>.V>=> vertices># No. of vertices> >self>.graph>=> defaultdict(>list>)># default dictionary to store graph> ># function to add an edge to graph> >def> addEdge(>self>, u, v):> >self>.graph[u].append(v)> >self>.graph[v].append(u)> ># A function used by isConnected> >def> DFSUtil(>self>, v, visited):> ># Mark the current node as visited> >visited[v]>=> True> ># Recur for all the vertices adjacent to this vertex> >for> i>in> self>.graph[v]:> >if> visited[i]>=>=> False>:> >self>.DFSUtil(i, visited)> >'''Method to check if all non-zero degree vertices are> >connected. It mainly does DFS traversal starting from> >node with non-zero degree'''> >def> isConnected(>self>):> ># Mark all the vertices as not visited> >visited>=> [>False>]>*>(>self>.V)> ># Find a vertex with non-zero degree> >for> i>in> range>(>self>.V):> >if> len>(>self>.graph[i]) !>=> 0>:> >break> ># If there are no edges in the graph, return true> >if> i>=>=> self>.V>->1>:> >return> True> ># Start DFS traversal from a vertex with non-zero degree> >self>.DFSUtil(i, visited)> ># Check if all non-zero degree vertices are visited> >for> i>in> range>(>self>.V):> >if> visited[i]>=>=> False> and> len>(>self>.graph[i])>>0>:> >return> False> >return> True> >'''The function returns one of the following values> >0 -->Če graf ni Eulerjev> >1 -->Če ima graf Eulerjevo pot (poleulerjevo)> >2 -->Če ima graf Eulerjevo vezje (Eulerjev) '''> >def> isEulerian(>self>):> ># Check if all non-zero degree vertices are connected> >if> self>.isConnected()>=>=> False>:> >return> 0> >else>:> ># Count vertices with odd degree> >odd>=> 0> >for> i>in> range>(>self>.V):> >if> len>(>self>.graph[i])>%> 2> !>=> 0>:> >odd>+>=> 1> >'''If odd count is 2, then semi-eulerian.> >If odd count is 0, then eulerian> >If count is more than 2, then graph is not Eulerian> >Note that odd count can never be 1 for undirected graph'''> >if> odd>=>=> 0>:> >return> 2> >elif> odd>=>=> 2>:> >return> 1> >elif> odd>>2>:> >return> 0> ># Function to run test cases> >def> test(>self>):> >res>=> self>.isEulerian()> >if> res>=>=> 0>:> >print>(>'graph is not Eulerian'>)> >elif> res>=>=> 1>:> >print>(>'graph has a Euler path'>)> >else>:> >print>(>'graph has a Euler cycle'>)> # Let us create and test graphs shown in above figures> g1>=> Graph(>5>)> g1.addEdge(>1>,>0>)> g1.addEdge(>0>,>2>)> g1.addEdge(>2>,>1>)> g1.addEdge(>0>,>3>)> g1.addEdge(>3>,>4>)> g1.test()> g2>=> Graph(>5>)> g2.addEdge(>1>,>0>)> g2.addEdge(>0>,>2>)> g2.addEdge(>2>,>1>)> g2.addEdge(>0>,>3>)> g2.addEdge(>3>,>4>)> g2.addEdge(>4>,>0>)> g2.test()> g3>=> Graph(>5>)> g3.addEdge(>1>,>0>)> g3.addEdge(>0>,>2>)> g3.addEdge(>2>,>1>)> g3.addEdge(>0>,>3>)> g3.addEdge(>3>,>4>)> g3.addEdge(>1>,>3>)> g3.test()> # Let us create a graph with 3 vertices> # connected in the form of cycle> g4>=> Graph(>3>)> g4.addEdge(>0>,>1>)> g4.addEdge(>1>,>2>)> g4.addEdge(>2>,>0>)> g4.test()> # Let us create a graph with all vertices> # with zero degree> g5>=> Graph(>3>)> g5.test()> # This code is contributed by Neelam Yadav>

>

>

C#


kazalec dereference c



// A C# program to check if a given graph is Eulerian or not> using> System;> using> System.Collections.Generic;> > // This class represents an undirected graph using adjacency list> // representation> public> class> Graph> {> >private> int> V;>// No. of vertices> > >// Array of lists for Adjacency List Representation> >private> List<>int>>[]adj;> > >// Constructor> >Graph(>int> v)> >{> >V = v;> >adj =>new> List<>int>>[in];> >for> (>int> i=0; i adj[i] = new List (); } //Funkcija za dodajanje roba v graf void addEdge(int v, int w) { adj[v].Add(w);// Dodaj w na seznam v. adj[w].Add(v); //Graf je neusmerjen } // Funkcija, ki jo uporablja DFS void DFSUtil(int v,bool []visited) { // Označi trenutno vozlišče kot obiskano visited[v] = true; // Ponavlja se za vse točke, ki mejijo na to točko foreach(int i in adj[v]){ int n = i; if (!visited[n]) DFSUtil(n, visited); } } // Metoda za preverjanje, ali so vsa oglišča, ki niso stopinje nič, // povezana. V glavnem izvaja prečkanje DFS, začenši z bool isConnected() { // Označi vse točke kot neobiskane bool []visited = new bool[V]; int i; for (i = 0; i visited[i] = false; // Najdi točko z različno stopnjo for (i = 0; i if (adj[i].Count != 0) break; // Če obstajajo brez robov v grafu, vrni true if (i == V) return true; // Začetek prečkanja DFS od točke z neničelno stopnjo DFSUtil(i, visited); // Preveri, ali so obiskane vse točke ne-ničelne stopnje for (i = 0; i if (visited[i] == false && adj[i].Count> 0) return false; return true; } /* Funkcija vrne eno od naslednjih vrednosti 0 --> Če je graf ni Eulerjev 1 --> Če ima graf Eulerjevo pot (pol-Eulerjev) 2 --> Če ima graf Eulerjevo vezje (Eulerjev) */ int isEulerian() { // Preveri, če so vsa oglišča brez ničelne stopnje povezana, če (isConnected() == false) return 0; // Štetje točk z liho stopnjo int odd = 0; for (int i = 0; i if (adj[i].Count%2!=0) odd++; // If število je večje od 2, potem graf ni Eulerjev, če (liho> 2) vrne 0; // Če je liho število 2, // Če je liho število 0, potem lahko liho število nikoli ne bo 1 za vrnitev neusmerjenega grafa (liho==2)? 1 : 2; } // Funkcija za izvajanje testnih primerov void test() { int res = isEulerian(); if (res == 0) Console.WriteLine('graf ni Eulerjev'); else if (res == 1) Console.WriteLine('graf ima Eulerjevo pot'); else Console.WriteLine('graf ima Eulerjev cikel'); } // Metoda gonilnika public static void Main(String []args) { // Ustvarimo in preizkusimo grafe, prikazane na zgornjih slikah Graph g1 = new Graph(5); g1.addEdge(1, 0); g1.addEdge(0, 2); g1.addEdge(2, 1); g1.addEdge(0, 3); g1.addEdge(3, 4); g1.test(); Graf g2 = nov graf(5); g2.addEdge(1, 0); g2.addEdge(0, 2); g2.addEdge(2, 1); g2.addEdge(0, 3); g2.addEdge(3, 4); g2.addEdge(4, 0); g2.test(); Graf g3 = nov graf(5); g3.addEdge(1, 0); g3.addEdge(0, 2); g3.addEdge(2, 1); g3.addEdge(0, 3); g3.addEdge(3, 4); g3.addEdge(1, 3); g3.test(); // Ustvarimo graf s 3 vozlišči // povezanimi v obliki cikla Graph g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Ustvarimo graf z vsemi vozlišči // z ničelno stopinjo Graph g5 = new Graph(3); g5.test(); } } // To kodo je prispeval PrinciRaj1992>

>

>

Javascript




kaj je zemljevid java
> // A Javascript program to check if a given graph is Eulerian or not> // This class represents an undirected graph using adjacency list> // representation> class Graph> {> >// Constructor> >constructor(v)> >{> >this>.V = v;> >this>.adj =>new> Array(v);> >for> (let i = 0; i this.adj[i] = []; } // Function to add an edge into the graph addEdge(v,w) { this.adj[v].push(w);// Add w to v's list. this.adj[w].push(v); //The graph is undirected } // A function used by DFS DFSUtil(v,visited) { // Mark the current node as visited visited[v] = true; // Recur for all the vertices adjacent to this vertex for(let i of this.adj[v]) { let n = i; if (!visited[n]) this.DFSUtil(n, visited); } } // Method to check if all non-zero degree vertices are // connected. It mainly does DFS traversal starting from isConnected() { // Mark all the vertices as not visited let visited = new Array(this.V); let i; for (i = 0; i 0) vrni false; vrni resnico; } /* Funkcija vrne eno od naslednjih vrednosti 0 --> Če graf ni Eulerjev 1 --> Če ima graf Eulerjevo pot (pol-Eulerjev) 2 --> Če ima graf Eulerjevo vezje (Eulerjevo) */ isEulerian() { // Preveri, če so vsa oglišča brez ničelne stopnje povezana if (this.isConnected() == false) return 0; // Štetje vozlišč z liho stopnjo naj bo liho = 0; za (naj bo i = 0; i2) vrni 0; // Če je liho število 2, potem pol-eulerjev. // Če je liho število 0, potem je Eulerian // Upoštevajte, da liho število nikoli ne more biti 1 za vrnitev neusmerjenega grafa (liho==2)? 1 : 2; } // Funkcija za izvajanje testnih primerov test() { let res = this.isEulerian(); if (res == 0) document.write('graf ni Eulerjev '); else if (res == 1) document.write('graf ima Eulerjevo pot '); else document.write('graf ima Eulerjev cikel '); } } // Metoda gonilnika // Ustvarimo in preizkusimo grafe, prikazane na zgornjih slikah let g1 = new Graph(5); g1.addEdge(1, 0); g1.addEdge(0, 2); g1.addEdge(2, 1); g1.addEdge(0, 3); g1.addEdge(3, 4); g1.test(); naj g2 = nov graf(5); g2.addEdge(1, 0); g2.addEdge(0, 2); g2.addEdge(2, 1); g2.addEdge(0, 3); g2.addEdge(3, 4); g2.addEdge(4, 0); g2.test(); naj g3 = nov graf(5); g3.addEdge(1, 0); g3.addEdge(0, 2); g3.addEdge(2, 1); g3.addEdge(0, 3); g3.addEdge(3, 4); g3.addEdge(1, 3); g3.test(); // Ustvarimo graf s 3 vozlišči // povezanimi v obliki cikla let g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Ustvarimo graf z vsemi vozlišči // z ničelno stopnjo let g5 = new Graph(3); g5.test(); // To kodo je prispeval avanitrachhadiya2155>

>

>

Izhod

graph has a Euler path graph has a Euler cycle graph is not Eulerian graph has a Euler cycle graph has a Euler cycle>

Časovna zahtevnost: O(V+E)

Kompleksnost prostora: O(V+E)

Naslednji članki:
Eulerjeva pot in vezje za usmerjene grafe.
Fleuryjev algoritem za tiskanje Eulerjeve poti ali vezja?