0

I am trying to implement the word ladder problem where I have to convert one word to another in shortest path possible.Obviously we can use the breadth first search (BFS) to solve it but before that we have to first draw the graph.I have implemented the concept of buckets where certain words fall under a bucket if they match the bucket type.But my graph is not implementing correctly.

The given word list is ["CAT", "BAT", "COT", "COG", "COW", "RAT", "BUT", "CUT", "DOG", "WED"]

So for each word I can create a bucket.For example for the word 'CAT', I can have three buckets _AT, C_T, CA_. Similarly I can create buckets for the rest of the words and which ever words match the bucket type will fall under those buckets.

Implementing with hand should give me a graph like this enter image description here

Since the graph is undirected, so for the vertex COG, its neighbouring vertices should be DOG, COW, COT (relationship work both ways) but instead I am getting COG is connected to nothing.Here is my code below

class Vertex:
    def __init__(self,key):
        self.id = key
        self.connectedTo = {}

    def addNeighbour(self,nbr,weight=0):
        self.connectedTo[nbr] = weight

    #string representation of the object
    def __str__(self):
        return str(self.id) + " is connected to " + str([x.id for x in self.connectedTo])

    def getConnections(self):
        return self.connectedTo.keys()

    def getId(self):
        return self.id

    def getWeight(self,nbr):
        return self.connectedTo[nbr]

class Graph:
    def __init__(self):
        self.vertList = {}
        self.numVertices = 0

    def addVertex(self,key):
        self.numVertices += 1
        newVertex = Vertex(key)
        self.vertList[key] = newVertex
        return newVertex

    def getVertex(self,n):
        if n in self.vertList:
            return self.vertList[n]
        else:
            return None

    def addEdge(self,f,t,cost=0):
        if f not in self.vertList:
            nv = self.addVertex(f)

        if t not in self.vertList:
            nv = self.addVertex(t)

        self.addVertex(f).addNeighbour(self.addVertex(t),cost)

    def getVertices(self):
        return self.vertList.keys()

    def __iter__(self):
        return iter(self.vertList.values())


wordList = ["CAT", "BAT", "COT", "COG", "COW", "RAT", "BUT", "CUT", "DOG", "WED"]

def buildGraph(wordList):
    d = {} #in this dictionary the buckets will be the keys and the words will be their values
    g = Graph()
    for i in wordList:
        for j in range(len(i)):
            bucket = i[:j] + "_" + i[j+1:]
            if bucket in d:
                #we are storing the words that fall under the same bucket in a list 
                d[bucket].append(i)
            else:
                d[bucket] = [i]

    # create vertices for the words under the buckets and join them
    #print("Dictionary",d)
    for bucket in d.keys():
        for word1 in d[bucket]:
            for word2 in d[bucket]:
                #we ensure same words are not treated as two different vertices
                if word1 != word2:
                    g.addEdge(word1,word2)

    return g

# get the graph object
gobj = buildGraph(wordList)

for v in gobj: #the graph contains a set of vertices
    print(v)

The result I get is

BUT is connected to ['BAT']
CUT is connected to ['COT']
COW is connected to ['COG']
COG is connected to []
CAT is connected to []
DOG is connected to ['COG']
RAT is connected to ['BAT']
COT is connected to []
BAT is connected to []

I was hoping the results to be something like

BUT is connected to ['BAT', 'CUT']
CUT is connected to ['CAT', 'COT', 'BUT']
and so on....

What am I doing wrong?

Souvik Ray
  • 2,899
  • 5
  • 38
  • 70

1 Answers1

2

The problem is in your addEdge method.

You are checking if vertices are already present in graph, ok. But if they are present, you are creating new vertices anyway and adding edge for those new vertices, throwing away the previous ones. That's why you have exactly one edge for each vertex in the end.

Just change the last line of addEdge to :

self.vertList[f].addNeighbour(self.vertList[t],cost)
Shihab Shahriar Khan
  • 4,930
  • 1
  • 18
  • 26
  • Wow!This is what I was doing all this time....recreating the vertices throwing away the old ones.Thanks for pointing that out! – Souvik Ray Nov 13 '17 at 18:10