コード例 #1
0
ファイル: word_ladder.py プロジェクト: arnabs542/algorithms-1
    def __init__(self, word_list):
        node_count = len(word_list)
        self.word_list = word_list
        self.graph = Graph(node_count)
        self.word_to_vertex_id = {}
        for i in xrange(node_count - 1):
            self.word_to_vertex_id[word_list[i]] = i
            for j in xrange(i + 1, node_count):
                word_distance = 0
                for k in xrange(len(word_list[i])):
                    if word_list[i][k] == word_list[j][k]:
                        continue
                    else:
                        word_distance += 1

                    if word_distance > 1:
                        break
                if word_distance == 1:
                    # add to graph as they are adjacent nodes in the graph
                    self.graph.add_edge(i, j)
コード例 #2
0
ファイル: word_ladder.py プロジェクト: arnabs542/algorithms-1
class WordLadder(object):
    """
    Assumes all words in input word_list are of same length, otherwise,
    innermost loop in constructor will degrade from O(m) to O(m^2) to compute
    levenshtein distances accounting for insertions and deletions as well.
    m = average number of letters per word
    """
    def __init__(self, word_list):
        node_count = len(word_list)
        self.word_list = word_list
        self.graph = Graph(node_count)
        self.word_to_vertex_id = {}
        for i in xrange(node_count - 1):
            self.word_to_vertex_id[word_list[i]] = i
            for j in xrange(i + 1, node_count):
                word_distance = 0
                for k in xrange(len(word_list[i])):
                    if word_list[i][k] == word_list[j][k]:
                        continue
                    else:
                        word_distance += 1

                    if word_distance > 1:
                        break
                if word_distance == 1:
                    # add to graph as they are adjacent nodes in the graph
                    self.graph.add_edge(i, j)

    def word_ladder(self, w1, w2):
        i1 = self.word_to_vertex_id[w1]
        i2 = self.word_to_vertex_id[w2]
        bfs = BreadthFirstPaths(self.graph, i1)
        path = []
        x = i2
        while x != i1:
            path.append(self.word_list[x])
            x = bfs.edge_to[x]
        path.append(self.word_list[x])
        return path
コード例 #3
0
 def __init__(self, rows, cols, startx, starty, endx, endy):
     self.rows = rows
     self.cols = cols
     self.startx = startx
     self.starty = starty
     self.endx = endx
     self.endy = endy
     self.graph = Graph(rows * cols)
     self.visited = [[False for _ in xrange(cols)] for r in xrange(rows)]
     q = deque()
     q.append((startx, starty))
     self.visited[startx][starty] = True
     while q:
         x, y = q.popleft()
         neighbors = self.next_knight_squares_from(x, y)
         for r, c in neighbors:
             self.graph.add_edge(self.get_vertex_id(x, y), self.get_vertex_id(r, c))
             if not self.visited[r][c]:
                 self.visited[r][c] = True
                 q.append((r, c))
コード例 #4
0
                x = vertex
                while x != adj:
                    try:
                        x = self.prev_to[x]
                        self.cycle.append(x)
                    except KeyError:
                        break
                self.cycle.append(adj)
                return


if __name__ == '__main__':

    from graph_api import Graph

    g = Graph()
    g.add_edge(0)
    g.add_edge(1, 0)
    g.add_edge(2, 0)
    g.add_edge(6, 0)
    g.add_edge(5, 0)
    g.add_edge(3, 1)
    g.add_edge(3, 2)
    g.add_edge(4, 2)
    g.add_edge(4, 6)
    g.add_edge(5, 0)
    g.add_edge(5, 4)

    bp = BipartiteGraph(g)
    assert bp.is_bipartite
コード例 #5
0
        :param graph_obj:
        :param src:
        :return:
        """
        self.dist_to[src] = 0
        self._marked[src] = True
        q = deque()
        q.append(src)
        while q:
            v = q.popleft()
            for u in graph_obj.adj(v):
                if not self._marked[u]:
                    self.dist_to[u] = self.dist_to[v] + 1
                    self.edge_to[u] = v
                    self._marked[u] = True
                    q.append(u)


if __name__ == '__main__':
    l = [
        13, 13, (0, 5), (4, 3), (0, 1), (9, 12), (6, 4), (5, 4), (0, 2),
        (11, 12), (9, 10), (0, 6), (7, 8), (9, 11), (5, 3)
    ]
    g = Graph(l)
    bfp = BreadthFirstPaths(g, 6)
    print bfp.edge_to  # [6, 0, 0, 4, 6, 0, None, None, None, None, None, None, None]
    print bfp._marked  # [True, True, True, True, True, True, True, False, False, False, False,
    # False, False]
    print bfp.dist_to  # [1, 2, 2, 2, 1, 2, 0, inf, inf, inf, inf, inf, inf]
    # shortest path array from src 6
コード例 #6
0
                x = vertex
                while x != adj:
                    try:
                        x = self.prev_to[x]
                        self.cycle.append(x)
                    except KeyError:
                        break
                self.cycle.append(adj)
                return


if __name__ == '__main__':

    from graph_api import Graph

    g = Graph()
    g.add_edge(0)
    g.add_edge(1, 0)
    g.add_edge(2, 0)
    g.add_edge(6, 0)
    g.add_edge(5, 0)
    g.add_edge(3, 1)
    g.add_edge(3, 2)
    g.add_edge(4, 2)
    g.add_edge(4, 6)
    g.add_edge(5, 0)
    g.add_edge(5, 4)

    bp = BipartiteGraph(g)
    assert bp.is_bipartite
コード例 #7
0
        self.graph = graph
        self.visited = []
        self.components = dict()
        # components counter
        self.count = 0
        do = DepthFirstOrder(graph)
        for v in do:
            if v not in self.visited:
                self.dfs(v)
                self.count += 1


if __name__ == '__main__':
    from graph_api import Graph

    g = Graph()
    g.add_edge(0)
    g.add_edge(1, 0)
    g.add_edge(2, 1)
    g.add_edge(3, 2)
    g.add_edge(4, 1)
    g.add_edge(5, 2)
    g.add_edge(6, 2)
    g.add_edge(7, 7)
    g.add_edge(8, 7)
    g.add_edge(9, 7)
    g.add_edge(10, 7)
    g.add_edge(11, 11)
    g.add_edge(12, 11)

    cc = ConnectedComponents(g)
コード例 #8
0
            try:
                vertex = self.prev_to[vertex]
            except KeyError:
                break
        path.append(vertex)
        return reversed(path)

    def distance(self, vertex):
        """
        Returns the minimum number of hops to the vertex from the starting vertex
        """
        return self.dist_to[vertex]

if __name__ == '__main__':
    from graph_api import Graph
    g = Graph()
    g.add_edge(0)
    g.add_edge(1, 0)
    g.add_edge(2, 1)
    g.add_edge(3, 2)
    g.add_edge(4, 1)
    g.add_edge(5, 2)
    g.add_edge(6, 2)
    g.add_edge(7, 3)
    g.add_edge(8, 7)
    g.add_edge(9, 7)
    g.add_edge(10, 7)

    dfs = DepthFirstPaths(g, 0)
    assert list(dfs.path_to(10)) == [0, 1, 2, 3, 7, 10]
    bfs = BreadthFirstPaths(g, 0)
コード例 #9
0
class Board(object):

    def __init__(self, rows, cols, startx, starty, endx, endy):
        self.rows = rows
        self.cols = cols
        self.startx = startx
        self.starty = starty
        self.endx = endx
        self.endy = endy
        self.graph = Graph(rows * cols)
        self.visited = [[False for _ in xrange(cols)] for r in xrange(rows)]
        q = deque()
        q.append((startx, starty))
        self.visited[startx][starty] = True
        while q:
            x, y = q.popleft()
            neighbors = self.next_knight_squares_from(x, y)
            for r, c in neighbors:
                self.graph.add_edge(self.get_vertex_id(x, y), self.get_vertex_id(r, c))
                if not self.visited[r][c]:
                    self.visited[r][c] = True
                    q.append((r, c))

    def get_minimum_moves(self):
        """
        this gets the minimum knight moves from (startx, starty) -> (endx, endy)
        :return:
        """
        # short circuit and return if end_cell not reachable
        if not self.visited[self.endx][self.endy]:
            return -1
        else:
            bfp = BreadthFirstPaths(self.graph, self.get_vertex_id(self.startx, self.starty))
            return bfp.dist_to[self.get_vertex_id(self.endx, self.endy)]

    def next_knight_squares_from(self, curr_row, curr_col):
        """
        :param curr_row:
        :param curr_col:
        :return: returns a list of valid (i,j) co-ordinates where a knight can move, given
        its starting co-ordinates as (curr_row, curr_col) on a rectangular board of dimension
        rows x cols
        """
        next_moves = [(curr_row + 2, curr_col + 1), ([curr_row + 2, curr_col - 1]),
                      (curr_row - 2, curr_col + 1), ([curr_row - 2, curr_col - 1]),
                      (curr_row + 1, curr_col + 2), ([curr_row + 1, curr_col - 2]),
                      (curr_row - 1, curr_col + 2), ([curr_row - 1, curr_col - 2])]
        valid_next_moves = filter(self.valid, [(i, j) for i, j in next_moves])
        return valid_next_moves

    def valid(self, coordinates):
        curr_row, curr_col = coordinates[0], coordinates[1]
        if 0 <= curr_row < self.rows and 0 <= curr_col < self.cols:
            return curr_row, curr_col

    def get_vertex_id(self, i, j):
        """
        returns the index in a 1-dimensional array-index that represents the graph nodes
        :param j:
        :param i:
        :param cols:
        :return: vertex_id which is an integer
        """
        return self.cols * i + j
コード例 #10
0
    """
    Topological sort of the DAG
    """

    def _dfs(self, vertex):
        self.visited.append(vertex)
        # iterate over edges not vertices since it is a DAG
        for edge in self.graph.iter_adjacent(vertex):
            v = edge.vertex_to()
            if v not in self.visited:
                self._dfs(v)
        # before exiting dfs - add the vertex to the list
        self.reversed_post.append(vertex)

if __name__ == '__main__':
    from graph_api import Graph
    g = Graph()
    g.add_edge(0)
    g.add_edge(5, 2)
    g.add_edge(6, 2)
    g.add_edge(1, 0)
    g.add_edge(4, 1)
    g.add_edge(7, 3)
    g.add_edge(8, 7)
    g.add_edge(2, 1)
    g.add_edge(3, 2)
    g.add_edge(9, 7)
    g.add_edge(10, 7)

    do = DepthFirstOrder(g)
    assert list(iter(g)) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
コード例 #11
0
        self.graph = graph
        self.visited = []
        self.components = dict()
        # components counter
        self.count = 0
        do = DepthFirstOrder(graph)
        for v in do:
            if v not in self.visited:
                self.dfs(v)
                self.count += 1


if __name__ == '__main__':
    from graph_api import Graph

    g = Graph()
    g.add_edge(0)
    g.add_edge(1, 0)
    g.add_edge(2, 1)
    g.add_edge(3, 2)
    g.add_edge(4, 1)
    g.add_edge(5, 2)
    g.add_edge(6, 2)
    g.add_edge(7, 7)
    g.add_edge(8, 7)
    g.add_edge(9, 7)
    g.add_edge(10, 7)
    g.add_edge(11, 11)
    g.add_edge(12, 11)

    cc = ConnectedComponents(g)