Eulerian sti er en bane i en graf som besøker hver kant nøyaktig én gang. Eulerian Circuit er en Eulerian Path som starter og slutter på samme toppunkt.
snø vs is

Hvordan finne ut om en gitt graf er Eulerian eller ikke?
Problemet er det samme som følgende spørsmål. Er det mulig å tegne en gitt graf uten å løfte blyanten fra papiret og uten å spore noen av kantene mer enn én gang.
En graf kalles eulerisk hvis den har en eulerisk syklus og kalles semi-eulerisk hvis den har en eulerisk bane. Problemet virker likt Hamiltonian Path som er NP komplett problem for en generell graf. Heldigvis kan vi finne om en gitt graf har en Eulerisk bane eller ikke i polynomisk tid. Faktisk kan vi finne det i O(V+E) tid.
Følgende er noen interessante egenskaper ved urettede grafer med en Eulersk bane og syklus. Vi kan bruke disse egenskapene til å finne ut om en graf er Eulersk eller ikke.
Eulerisk syklus: En urettet graf har Eulerisk syklus hvis følgende to forhold er sanne.
- Alle hjørner med ikke-null grader er koblet sammen. Vi bryr oss ikke om hjørner med null grader fordi de ikke tilhører Eulerian Cycle eller Path (vi vurderer bare alle kanter).
- Alle hjørner har jevn grad.
Eulerisk sti: En urettet graf har Eulerian Path hvis følgende to forhold er sanne.
- Samme som betingelse (a) for Eulerian Cycle.
- Hvis null eller to toppunkter har oddetall og alle andre toppunkter har partall grad. Merk at bare ett toppunkt med oddetall ikke er mulig i en urettet graf (summen av alle grader er alltid partall i en urettet graf)
Legg merke til at en graf uten kanter betraktes som Eulersk fordi det ikke er noen kanter å krysse.
Hvordan virker dette?
I Eulersk bane, hver gang vi besøker et toppunkt v, går vi gjennom to ubesøkte kanter med ett endepunkt som v. Derfor må alle midtpunkt i Eulerian Path ha jevn grad. For Eulerian Cycle kan ethvert toppunkt være midtpunkt, derfor må alle toppunkter ha jevn grad.
Gjennomføring:
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>>[I]; }> >~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) returner falsk; return true; } /* Funksjonen returnerer en av følgende verdier 0 --> Hvis grafen ikke er Eulersk 1 --> Hvis grafen har en Euler-bane (Semi-Eulerian) 2 --> Hvis grafen har en Euler-krets (Eulerian) */ int Graph::isEulerian() { // Sjekk om alle toppunkter som ikke er null grader er koblet sammen hvis (isConnected() == usann) returnerer 0; // Tell toppunkter med oddetall int odd = 0; for (int i = 0; i if (adj[i].size() & 1) odd++; // Hvis antallet er mer enn 2, så er ikke grafen Eulerian if (odde> 2) returner 0; // Hvis oddetall count er 2, deretter semi-eulerian // Hvis oddetall er 0, så eulerian // Merk at oddetall aldri kan være 1 for urettet graf return (odd) } // Funksjon for å kjøre testcases test(Graph &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; }> |
bæsj
>
>
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) returner falsk; return true; } /* Funksjonen returnerer en av følgende verdier 0 --> Hvis grafen ikke er Eulersk 1 --> Hvis grafen har en Euler-bane (Semi-Eulerian) 2 --> Hvis grafen har en Euler-krets (Eulerian) */ int isEulerian() { // Sjekk om alle ikke-null graders hjørner er koblet hvis (isConnected() == usann) returnerer 0; // Tell toppunkter med oddetall int odd = 0; for (int i = 0; i if (adj[i].size()%2!=0) odd++; // Hvis antallet er mer enn 2, er ikke grafen Eulerian if (odde> 2) returnerer 0; / / Hvis oddetall er 2, så semi-eulerian er 0, så eulerian // Merk at oddetall aldri kan være 1 for urettet graf returnerer (odd==2)? Funksjon for å kjøre testtilfeller void test() { int res = isEulerian(); out.println('grafen har en Euler-bane'); else System.out.println('grafen har en Euler-syklus' } // Drivermetode public static void main(String args[]) { / / La oss lage og teste grafer vist i figurene ovenfor. Graph g1.addEdge(1, 0); (0, 3); g1.addEdge(3, 4); addEdge(2, 1); .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(); // La oss lage en graf med 3 toppunkter // koblet sammen i form av syklus Graph g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // La oss lage en graf med alle toppunkter // med null grader Graph g5 = new Graph(3); g5.test(); } } // Denne koden er bidratt av Aakash Hasija> |
>
>
Python3
svever i css
# 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 -->Hvis grafen ikke er Eulerian> >1 -->Hvis grafen har en Euler-bane (Semi-Eulerian)> >2 -->Hvis grafen har en Euler-krets (Eulerian) '''> >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#
// 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>>[i];> >for> (>int> i=0; i adj[i] = new List |
>
>
Javascript
konverter streng til json-objekt
> // 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 |
>
>Produksjon
graph has a Euler path graph has a Euler cycle graph is not Eulerian graph has a Euler cycle graph has a Euler cycle>
Tidskompleksitet: O(V+E)
Romkompleksitet: O(V+E)
Neste artikler:
Eulerian Path and Circuit for a Directed Graphs.
Fleurys algoritme for å skrive ut en Eulerisk bane eller krets?