Pages

Saturday, June 3, 2017

Python: Determine whether a graph has an Euler circuit, Euler path or neither

Given the set of vertices and vertex pairs associated to the edges of a directed graph, find the in-degree and out-degree of each vertex, and state whether the graph has Euler circuit, Euler path, or not.

Example of an input (from keyboard):
Set of vertices: a,b,c
Edges: (a,b), (a,c), (b,a),(b,c)

We are giving the solution using Python:

def EulerCPN():
    print("Enter every input separated by comma (,) \n")
    print("Ex: \nSet of vertices: a,b,c \nEdges: (a,b),(a,c),(b,a),(b,c) \n")

    sov = input("Set of vertices: ")  # Get vertices letter from input
    Ssov = sov.split(",")       # Splitting vertices from input delimited from commas and putting them into array

    edg = input("Edges: ")
    edg1 = edg.replace(",", "")     # Deleting all commas (,) from the input edges
    edg2 = edg1.replace("(", "")    # Deleting all open parenthesis from the input edges
    edg3 = edg2.replace(")", "")    # Deleting all closing parenthesis from the input edges
 
    outdeg = []     # Creating empty out-degree list
    indeg = []      # Creating empty in-degree list

    odCounter = 0   # Declaring out-degree counter equal to 0
    idCounter = 0   # Declaring in-degree counter equal to 0

    equalDegrees = 0     # Variable to accumulate whenever degrees in and out are equal
    notEqualDegrees = 0

    EPEequalDegrees = 0  # Variable to accumulate every even vertex
    EPOequalDegrees = 0

    ECreason = 0        # Variable for the reason of not having an Euler Circuit reason
    EPreason = 0        # Variable for the reason of not having an Euler Path reason


    eulerPath = False
    ep1 = 0
    ep2 = 0

    eulerCircuit = False
    ec = 0

    forCounter = 0

    for j in Ssov:  ## Iterate through each vertex

        ## See if vertex if equal to out-degree

        ## Out-degree
        for i in range(0, len(edg3), 2):
            op, code = edg3[i:i+2]  ## Get edges 2 by 2 from the edges list and assigning the first letter to op and the second to code
                                    ## op will compare out-degree. code will compare in-degree

            if j == op:  ## If the current vertex is equal to the first out-degree occurrence ads to the counter
                odCounter = odCounter + 1  ## Add an out-degree to a vertex

        outdeg.append(odCounter)  ## Add the amount of out-degree occurrences for a vertex into outdeg list
        odCounter = 0; ## Set odCounter equals to 0

        ## In-degree
        ## Repeat all steps from Out-degree into in-degree
        for i in range(0, len(edg3), 2):
            op, code = edg3[i:i+2]

         
            if j == code:
                odCounter = odCounter + 1

        indeg.append(odCounter)
        odCounter = 0;

    for j,o,i in zip(Ssov,outdeg,indeg):
        print(str('deg-('),j,str(')= '),o, str(', deg+('),j,str(')= '),i,  str('\n')) # Printing the values for every vertex letter and corresponding in and out degrees


    ## Check for Euler circuit
     
        if (o == i):
            equalDegrees = equalDegrees + 1 ## Everytime an out-degree and in-degree vertex are equal add to the counter
        else:
            notEqualDegrees = notEqualDegrees + 1   ## Everytime an out-degree and in-degree vertex are not equal add to the counter
         
        if (notEqualDegrees == 0): ## If the vertices where never not equal then we have an Euler Circuit
            eulerCircuit = True
        else:
            eulerCircuit = False
            ECreason = 2
         

    ## Check for Euler Path
        if ((o-i) == 1):
            ep1 = ep1 + 1

        if ((i-o) == 1):
            ep2 = ep2 + 1
     

        ## Check that every other vertex have in-degree = to out-degree
        ## When even
        if ((forCounter%2) == 0):
            if (o == i):
                EPEequalDegrees = EPEequalDegrees + 1
        else:
            if (o == i):
                EPOequalDegrees = EPOequalDegrees + 1
        forCounter = forCounter +1

    ## End for


 
    if (EPEequalDegrees >= 1 or EPOequalDegrees >= 1):
        if (ep1 == 1 and ep2 == 1):
            eulerPath = True
        else:
            eulerPath = False
            EPreason = 1
    else:
        EPreason = 2

 
    print(str('Euler Circuit: '),eulerCircuit)
    print(str('Euler Path: '),eulerPath)

    if (eulerCircuit == True):
        print("The graph has an Euler Circuit")
    else:
        if (ECreason == 2):
            print("The graph doesn't have an Euler circuit because the In-degree and out-degree of every vertex is not the same")

    if (eulerPath == True):
        print("The graph has an Euler Path")
    else:
        if (EPreason == 1):
            print("The graph doesn't have an Euler path because neither at most one vertex has (out-degree) − (in-degree) = 1, nor it has at most one vertex has (in-degree) − (out-degree) = 1")
        elif(EPreason == 2):
            print("The graph doesn't have an Euler path because every other vertex doesn't have in-degree = out-degree")


EulerCPN()