logo

Eulersk sti og kredsløb for urettet graf

Eulerian sti er en sti i en graf, der besøger hver kant nøjagtigt én gang. Eulerian Circuit er en Eulersk sti, der starter og slutter på samme toppunkt.

Euler1



css overgangsopacitet

Euler2

Euler3

Hvordan finder man ud af, om en given graf er Eulersk eller ej?



Problemet er det samme som det følgende spørgsmål. Er det muligt at tegne en given graf uden at løfte blyanten fra papiret og uden at spore nogen af ​​kanterne mere end én gang.
En graf kaldes Eulersk, hvis den har en Eulersk cyklus og kaldes semi-eulerisk, hvis den har en Eulersk sti. Problemet ligner Hamiltonian Path, som er NP komplet problem for en generel graf. Heldigvis kan vi finde ud af, om en given graf har en Eulerian Path eller ej i polynomisk tid. Faktisk kan vi finde det i O(V+E) tid.
Følgende er nogle interessante egenskaber ved urettede grafer med en Eulersk sti og cyklus. Vi kan bruge disse egenskaber til at finde ud af, om en graf er Eulersk eller ej.

Eulersk cyklus: En urettet graf har Eulersk cyklus, hvis følgende to betingelser er sande.

  1. Alle hjørner med ikke-nul grader er forbundet. Vi er ligeglade med hjørner med nul grader, fordi de ikke tilhører Eulerian Cycle eller Path (vi betragter kun alle kanter).
  2. Alle hjørner har lige grad.

Eulerian sti: En urettet graf har Eulerian Path, hvis følgende to betingelser er sande.



  1. Samme som betingelse (a) for Eulersk cyklus.
  2. Hvis nul eller to hjørner har ulige grad, og alle andre hjørner har lige grad. Bemærk, at kun et toppunkt med ulige grad ikke er muligt i en urettet graf (summen af ​​alle grader er altid lige i en urettet graf)

Bemærk, at en graf uden kanter betragtes som Eulerian, fordi der ikke er nogen kanter at krydse.

Hvordan virker det?
I Eulersk sti går vi, hver gang vi besøger et toppunkt v, gennem to ubesøgte kanter med det ene endepunkt som v. Derfor skal alle midterpunkter i Eulersk sti have lige grad. For Eulersk cyklus kan ethvert toppunkt være midterpunkt, derfor skal alle toppunkter have lige grad.

Anbefalet praksis Euler-kredsløb og sti Prøv det!

Implementering:

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) returnere falsk; returnere sandt; } /* Funktionen returnerer en af ​​følgende værdier 0 --> Hvis grafen ikke er Eulersk 1 --> Hvis grafen har en Euler-sti (semi-eulerisk) 2 --> Hvis grafen har en Euler-kredsløb (Eulerian) */ int Graph::isEulerian() { // Tjek om alle ikke-nul graders hjørner er forbundet, hvis (isConnected() == falsk) returnerer 0; // Tæl toppunkter med ulige grad int ulige = 0; for (int i = 0; i if (adj[i].size() & 1) ulige++; // Hvis antallet er mere end 2, er grafen ikke Eulerian if (ulige> 2) returnerer 0; // Hvis ulige count er 2, så semi-eulerian // Hvis ulige antal er 0, så eulerian // Bemærk at ulige count aldrig kan være 1 for urettet graf returnerer (ulige) } // Funktion til at kø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; }>

lort

>

>

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) returnere falsk; returnere sandt; } /* Funktionen returnerer en af ​​følgende værdier 0 --> Hvis grafen ikke er Eulersk 1 --> Hvis grafen har en Euler-sti (semi-eulerisk) 2 --> Hvis grafen har en Euler-kredsløb (Eulerian) */ int isEulerian() { // Tjek, om alle ikke-nul graders hjørner er forbundet, hvis (isConnected() == falsk) returnerer 0; // Tæl toppunkter med ulige grad int ulige = 0; for (int i = 0; i if (adj[i].size()%2!=0) ulige++; // Hvis antallet er mere end 2, så er grafen ikke Eulerian if (ulige> 2) returnerer 0; / / Hvis ulige tæller er 2, så semi-eulerian er 0, så eulerian // Bemærk at ulige count aldrig kan være 1 for urettet graf returnerer (ulige==2)? Funktion til at køre testcases void test() { int res = isEulerian(); out.println('graf har en Euler-sti'); else System.out.println('graf har en Euler-cyklus' } // Driver-metode public static void main(String args[]) { / / Lad os oprette og teste grafer vist i ovenstående figurer. Graph g1.addEdge(1, 0), g1.addEdge(2; (0, 3); g1.addEdge(3, 4); addEdge(2, 1, g2.addEdge(3, 4, 0) 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(); // Lad os lave en graf med 3 toppunkter // forbundet i form af cyklus Graph g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Lad os lave en graf med alle hjørner // med nul grader Graph g5 = new Graph(3); g5.test(); } } // Denne kode er bidraget af Aakash Hasija>

>

>

Python3


numpy meshgrid



# 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-sti (semi-eulerisk)> >2 -->Hvis grafen har et Euler-kredsløb (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 (); } //Funktion til at tilføje en kant i grafen void addEdge(int v, int w) { adj[v].Add(w);// Tilføj w til v's liste. adj[w].Add(v); //Graffen er ikke-rettet } // En funktion brugt af DFS void DFSUtil(int v,bool []besøgt) { // Marker den aktuelle node som besøgt besøgt[v] = sand; // Gentag for alle de hjørner, der støder op til dette vertex foreach(int i i adj[v]){ int n = i; hvis (!besøgt[n]) DFSUtil(n, besøgt); } } // Metode til at kontrollere, om alle ikke-nul graders hjørner er // forbundet. Den udfører hovedsageligt DFS-traversal startende fra bool isConnected() { // Marker alle hjørnerne som ikke besøgt bool []visited = new bool[V]; int i; for (i = 0; jeg besøgte[i] = falsk; // Find et toppunkt med ikke-nul grad for (i = 0; i hvis (adj[i].Tæller != 0) brud; // Hvis der er ingen kanter i grafen, returner sandt hvis (i == V) returnerer sandt // Start DFS-gennemløb fra et toppunkt med ikke-nul grad DFSUtil(i, besøgt // Kontroller om alle ikke-nul graders toppunkter er besøgt). for (i = 0; i if (besøgt[i] == falsk && adj[i].Tæller> 0) returner falsk; return true; } /* Funktionen returnerer en af ​​følgende værdier 0 --> Hvis grafen er ikke Eulerian 1 --> Hvis grafen har en Euler-sti (Semi-Eulerian) 2 --> Hvis grafen har en Euler-kredsløb (Eulerian) */ int isEulerian() { // Tjek om alle ikke-nul graders hjørner er forbundet hvis (isConnected() == false) return 0; // Tæl toppunkter med ulige grad int ulige = 0 for (int i = 0; i if (adj[i].Count%2!=0) ulige++; // If count er mere end 2, så er grafen ikke Eulerian if (ulige> 2) return 0; aldrig være 1 for urettet grafretur (ulige==2)? 1:2; } // Funktion til at køre testcases void test() { int res = isEulerian(); if (res == 0) Console.WriteLine('grafen er ikke Eulerian'); else if (res == 1) Console.WriteLine('graf har en Euler-sti'); else Console.WriteLine('graf har en Euler-cyklus'); } // Drivermetode public static void Main(String []args) { // Lad os oprette og teste grafer vist i ovenstående figurer 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(); Graph g2 = new 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(); Graph g3 = new 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(); // Lad os lave en graf med 3 toppunkter // forbundet i form af cyklus Graph g4 = new Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Lad os lave en graf med alle hjørner // med nul grader Graph g5 = new Graph(3); g5.test(); } } // Denne kode bidraget af PrinciRaj1992>

>

>

Javascript




kan en abstrakt klasse have en konstruktør

> // 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) returnere falsk; returnere sandt; } /* Funktionen returnerer en af ​​følgende værdier 0 --> Hvis grafen ikke er Eulersk 1 --> Hvis grafen har en Euler-sti (semi-eulerisk) 2 --> Hvis grafen har en Euler-kredsløb (Eulerian) */ isEulerian() { // Tjek, om alle ikke-nul graders hjørner er forbundet, hvis (this.isConnected() == false) returnerer 0; // Tæl toppunkter med ulige grad lad ulige = 0; for (lad i = 0; i2) returner 0; // Hvis ulige tal er 2, så semi-eulerian. // Hvis ulige antal er 0, så eulerian // Bemærk, at ulige antal aldrig kan være 1 for urettet grafretur (ulige==2)? 1:2; } // Funktion til at køre testcases test() { let res = this.isEulerian(); if (res == 0) document.write('grafen er ikke Eulersk '); else if (res == 1) document.write('graf har en Euler-sti '); else document.write('graf har en Euler-cyklus '); } } // Drivermetode // Lad os oprette og teste grafer vist i ovenstående figurer lad 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(); lad g2 = ny 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(); lad g3 = ny 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(); // Lad os lave en graf med 3 toppunkter // forbundet i form af cyklus lad g4 = ny Graph(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); g4.test(); // Lad os lave en graf med alle hjørner // med nul grader lad g5 = new Graph(3); g5.test(); // Denne kode er bidraget af avanitrachhadiya2155>

>

>

Produktion

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)

Rumkompleksitet: O(V+E)

Næste artikler:
Eulersk sti og kredsløb for en rettet grafer.
Fleurys algoritme til at udskrive en Eulersk sti eller kredsløb?