-3

I've got this code in Python. The user writes graph's adjency list and gets the information if the graph has an euler circuit, euler path or isn't eulerian. Everything worked just fine until I wrote this at the end: ln1 = [1, 2, 1, 6, 2, 3, 3, 4, 4, 5, 5, 6] The output should be: graph has a Euler circuit. Could you please correct this code? I have no idea what the problem is

# 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]) > 1:
                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 --> If grpah is not Eulerian
       1 --> If graph has an Euler path (Semi-Eulerian)
       2 --> If graph has an Euler Circuit (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"





ln1 = [1, 2, 1, 6, 2, 3, 3, 4, 4, 5, 5, 6]
#ln1 = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 4, 1, 5, 2, 3, 2, 4, 3, 5, 4, 5] #euler path
#ln1 = [1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6, 3, 4, 3, 5, 4, 6, 5, 6] #euler path
g1 = Graph(len(ln1)/2)
i = 0
j = 1
while i + 2 <= len(ln1) and j + 1 <= len(ln1):
    g1.addEdge(ln1[i], ln1[j])
    i += 2
    j += 2
g1.test()
Matthew
  • 67
  • 1
  • 9

2 Answers2

0

Have you tried replacing visited = [False] * (self.V) with visited = [False] * int(self.V)?

Since this problem does not only occur at this line, you should probably init your class with:

self.V = int(vertices)  # No. of vertices

Imho the number of vertices should be an integer anyways.

But there seem to be alot more problems. For example you have a return statement in isConnected after an if clause which is depending on i. But i is used in the loop before. So this should only be valid, if it is really only depending on the last index (seems to be ok in this case).

Furthermore you don't save you changes to visited since it is a method variable but not an instance variable. So visited will remain set to False.

Next problem: In DFSUtil in

# Recur for all the vertices adjacent to this vertex
for i in self.graph[v]:
    if visited[i] == False:
        self.DFSUtil(i, visited)

a list with for example [0, 6] is returned from self.graph[v] for v=5. But the index 6 is out of range for visited with length 6.

JE_Muc
  • 5,403
  • 2
  • 26
  • 41
0

I have modified DFSUtil loop and changed v to v+1:

for i in self.graph[v+1]:
      if visited[i] == False:
      self.DFSUtil(i, visited)

And now the program starts but in the output it says: "Graph is not Eulerian". It should say of course "Graph has a Euler circuit".

Matthew
  • 67
  • 1
  • 9
  • You should go through your program step by step. And I'm always willing to extend my help, if I can see any appreciation for what I've done so far, for example with upvotes or accepting my answer. – JE_Muc May 14 '18 at 09:31