def _dfs(self, G, v): self._marked[v] = True for w in G.adj(v): # short circuit if odd-length cycle found if self._cycle is not None: return # found uncolored vertex, so recur if not self._marked[w]: self._edge_to[w] = v self._color[w] = not self._color[v] self._dfs(G, w) # if v-w create an odd-length cycle, find it elif self._color[w] == self._color[v]: self._is_bipartite = False self._cycle = Stack() self._cycle.push( w ) # don't need this unless you want to include start vertex twice x = v while x != w: self._cycle.push(x) x = self._edge_to[x] self._cycle.push(w)
def _dfs(self, G, v): self._onStack[v] = True self._marked[v] = True for e in G.adj(v): w = e.to_vertex() # short circuit if directed cycle found if self._cycle is not None: return # found new vertex, so recur elif not self._marked[w]: self._edgeTo[w] = e self._dfs(G, w) # trace back directed cycle elif self._onStack[w]: self._cycle = Stack() f = e while f.from_vertex() != w: self._cycle.push(f) f = self._edgeTo[f.from_vertex()] self._cycle.push(f) return self._onStack[v] = False
def reverse_post(self): """ Returns the vertices in reverse postorder. :return: the vertices in reverse postorder, as an iterable of vertices """ reverse = Stack() for v in self._postorder: reverse.push(v) return reverse
def path_to(self, v): self._validate_vertex(v) if self.has_negative_cycle(): raise UnsupportedOperationException("Negative cost cycle exists") if not self.has_path_to(v): return None path = Stack() e = self._edgeTo[v] while e is not None: path.push(e) e = self._edgeTo[e.from_vertex()] return path
def _has_self_loop(self, G): # does this graph have a self loop? # side effect: initialize cycle to be self loop for v in range(G.V()): for w in G.adj(v): if v == w: self._cycle = Stack() self._cycle.push(v) self._cycle.push(w) return True return False
def from_graph(G): """ Initializes a new edge-weighted graph that is a deep copy of G. :param G: the edge-weighted graph to copy :return: the copy of the graph edge-weighted graph G :rtype: EdgeWeightedGraph """ g = EdgeWeightedGraph(G.V()) g._E = G.E() for v in range(G.V()): reverse = Stack() for e in G.adj(v): reverse.push(e) for e in reverse: g._adj[v].add(e) return g
def from_graph(G): """ Initializes a new graph that is a deep copy of G :param G: the graph to copy :returns: copy of G """ g = Graph(G.V()) g._E = G.E() for v in range(G.V()): # reverse so that adjacency list is in same order as original reverse = Stack() for w in G._adj[v]: reverse.push(w) for w in reverse: g._adj[v].add(w)
def path_to(self, v): """ Returns a longest path from the source vertex s to vertex v. :param: the destination vertex :returns: a longest path from the source vertex s to vertex v as an iterable of edges, and None if no such path """ self._validate_vertex(v) if not self.has_path_to(v): return None path = Stack() edge = self._edge_to[v] while not edge is None: path.push(edge) edge = self._edge_to[edge.from_vertex()] return path
def path_to(self, v): """ Returns a shortest path from the source vertex s to vertex v. :param v: the destination vertex :returns: a shortest path from the source vertex s to vertex v as an iterable of edges, and None if no such path :raises ValueError: unless 0 <= v < V """ self._validate_vertex(v) if not self.has_path_to(v): return None path = Stack() e = self._edge_to[v] while e is not None: path.push(e) e = self._edge_to[e.from_vertex()] return path
def _dfs(self, G, u, v): self._marked[v] = True for w in G.adj(v): # short circuit if cycle already found if self._cycle is not None: return if not self._marked[w]: self._edgeTo[w] = v self._dfs(G, v, w) elif w != u: self._cycle = Stack() x = v while x != w: self._cycle.push(x) x = self._edgeTo[x] self._cycle.push(w) self._cycle.push(v)
def path_to(self, v): """ Returns a shortest path from the source vertex s to vertex v. :param v: the destination vertex :return: a shortest path from the source vertex s to vertex v :rtype: collections.iterable[DirectedEdge] :raises IllegalArgumentException: unless 0 <= v < V """ self._validate_vertex(v) if not self.has_path_to(v): return None path = Stack() e = self._edge_to[v] while e is not None: path.push(e) e = self._edge_to[e.from_vertex()] return path
def __init__(self, regex): """ Initializes the NFA from the specified regular expression. :param regex: the regular expression """ self.regex = regex m = len(regex) self.m = m ops = Stack() graph = Digraph(m + 1) for i in range(0, m): lp = i if (regex[i] == '(' or regex[i] == '|'): ops.push(i) elif (regex[i] == ')'): or_ = ops.pop() # 2-way or operator if (regex[or_] == '|'): lp = ops.pop() graph.add_edge(lp, or_ + 1) graph.add_edge(or_, i) elif (regex[or_] == '('): lp = or_ else: assert False if (i < m - 1 and regex[i + 1] == '*'): graph.add_edge(lp, i + 1) graph.add_edge(i + 1, lp) if (regex[i] == '(' or regex[i] == '*' or regex[i] == ')'): graph.add_edge(i, i + 1) if (ops.size() != 0): raise ValueError("Invalid regular expression") self.graph = graph
def _has_parallel_edges(self, G): # does this graph have two parallel edges? # side effect: initialize cycle to be two parallel edges self._marked = [False] * G.V() for v in range(G.V()): # check for parallel edges incident to v for w in G.adj(v): if self._marked[w]: self._cycle = Stack() self._cycle.push(v) self._cycle.push(w) self._cycle.push(v) return True self._marked[w] = True for w in G.adj(v): self._marked[w] = False return False
def path_to(self, v): """ Returns a shortest path between the source vertex s and vertex v. :param v: the destination vertex :return: a shortest path between the source vertex s and vertex v. None if no such path :rtype: collections.iterable[Edge] :raises IllegalArgumentException: unless 0 <= v < V """ self._validate_vertex(v) if not self.has_path_to(v): return None path = Stack() x = v e = self._edge_to[v] while e is not None: edge = self._edge_to[x] path.push(edge) x = e.other(x) e = self._edge_to[x] return path
def _dfs(self, digraph, v): self._on_stack[v] = True self._marked[v] = True for w in digraph.adj(v): # short circuit if directed cycle found if self.has_cycle(): return # found new vertex, so recur elif not self._marked[w]: self._edge_to[w] = v self._dfs(digraph, w) # trace back directed cycle elif self._on_stack[w]: self._cycle = Stack() x = v while x != w: self._cycle.push(x) x = self._edge_to[x] self._cycle.push(w) self._cycle.push(v) self._on_stack[v] = False
def _dfs(self, graph, v): self._on_stack[v] = True self._marked[v] = True for edge in graph.adj(v): w = edge.to_vertex() # short circuit if directed cycle found if self.has_cycle(): return # found new vertex, so recur elif not self._marked[w]: self._edge_to[w] = edge self._dfs(graph, w) # trace back directed cycle elif self._on_stack[w]: self._cycle = Stack() f = edge while f.from_vertex() != w: self._cycle.push(f) f = self._edge_to[f.from_vertex()] self._cycle.push(f) self._on_stack[v] = False
def path_to(self, v): if not self.has_path_to(v): return None path = Stack() x = v while x != self._s: path.push(x) x = self._edgeTo[x] path.push(self._s) return path
def path_to(self, v): """ Returns a shortest path between the source vertex s (or sources) and v, or null if no such path. :param v: the vertex :returns: the sequence of vertices on a shortest path, as an Iterable :raises ValueError: unless 0 <= v < V """ if not self.has_path_to(v): return None path = Stack() x = v while self._dist_to[x] != 0: path.push(x) x = self._edgeTo[x] path.push(x) return path
def path_to(self, v): """ Returns a path between the source vertex s and vertex v, or None if no such path. :param v: the vertex :returns: the sequence of vertices on a path between the source vertex s and vertex v, as an Iterable :raises ValueError: unless 0 <= v < V """ self._validateVertex(v) if not self.has_path_to(v): return None path = Stack() w = v while w != self._s: path.push(w) w = self._edgeTo[w] path.push(self._s) return path
class DirectedCycle: """ The DirectedCycle class represents a data type for determining whether a digraph has a directed cycle. The hasCycle operation determines whether the digraph has a directed cycle and, and of so, the cycle operation returns one. This implementation uses depth-first search. The constructor takes time proportional to V + E (in the worst case), where V is the number of vertices and E is the number of edges. Afterwards, the hasCycle operation takes constant time; the cycle operation takes time proportional to the length of the cycle. See Topological to compute a topological order if the digraph is acyclic. For additional documentation, see Section 4.2 of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. """ def __init__(self, digraph): """ Determines whether the digraph has a directed cycle and, if so, finds such a cycle. :digraph: the digraph """ self._cycle = None self._on_stack = [False] * digraph.V() self._edge_to = [0] * digraph.V() self._marked = [False] * digraph.V() for v in range(digraph.V()): if not self._marked[v]: self._dfs(digraph, v) # check that algorithm computes either the topological order or finds a directed cycle def _dfs(self, digraph, v): self._on_stack[v] = True self._marked[v] = True for w in digraph.adj(v): # short circuit if directed cycle found if self.has_cycle(): return # found new vertex, so recur elif not self._marked[w]: self._edge_to[w] = v self._dfs(digraph, w) # trace back directed cycle elif self._on_stack[w]: self._cycle = Stack() x = v while x != w: self._cycle.push(x) x = self._edge_to[x] self._cycle.push(w) self._cycle.push(v) self._on_stack[v] = False def has_cycle(self): """ Does the digraph have a directed cycle? :returns: true if there is a cycle, false otherwise """ return self._cycle != None def cycle(self): """ Returns a directed cycle if the digraph has a directed cycle, and null otherwise. :returns: a directed cycle (as an iterable) if the digraph has a directed cycle, and null otherwise """ return self._cycle
class Cycle: """ The Cycle class represents a data type for determining whether an undirected graph has a cycle. The hasCycle operation determines whether the graph has a cycle and, if so, the cycle operation returns one. This implementation uses depth-first search. The constructor takes time proportional to V + E (in the worst case), where V is the number of vertices and E is the number of edges. Afterwards, the hasCycle operation takes constant time the cycle operation takes time proportional to the length of the cycle. """ def __init__(self, G): """ Determines whether the undirected graph G has a cycle and, if so, finds such a cycle. :param G: the undirected graph """ if self._has_self_loop(G): return if self._has_parallel_edges(G): return self._marked = [False] * G.V() self._edgeTo = [0] * G.V() self._cycle = None for v in range(G.V()): if not self._marked[v]: self._dfs(G, -1, v) def _has_self_loop(self, G): # does this graph have a self loop? # side effect: initialize cycle to be self loop for v in range(G.V()): for w in G.adj(v): if v == w: self._cycle = Stack() self._cycle.push(v) self._cycle.push(w) return True return False def _has_parallel_edges(self, G): # does this graph have two parallel edges? # side effect: initialize cycle to be two parallel edges self._marked = [False] * G.V() for v in range(G.V()): # check for parallel edges incident to v for w in G.adj(v): if self._marked[w]: self._cycle = Stack() self._cycle.push(v) self._cycle.push(w) self._cycle.push(v) return True self._marked[w] = True for w in G.adj(v): self._marked[w] = False return False def has_cycle(self): """ Returns true if the graph G has a cycle. :returns: true if the graph has a cycle false otherwise """ return self._cycle is not None def cycle(self): """ Returns a cycle in the graph G. :returns: a cycle if the graph G has a cycle, and null otherwise """ return self._cycle def _dfs(self, G, u, v): self._marked[v] = True for w in G.adj(v): # short circuit if cycle already found if self._cycle is not None: return if not self._marked[w]: self._edgeTo[w] = v self._dfs(G, v, w) elif w != u: self._cycle = Stack() x = v while x != w: self._cycle.push(x) x = self._edgeTo[x] self._cycle.push(w) self._cycle.push(v)
class Bipartite: """ The Bipartite class represents a data type for determining whether an undirected graph is bipartite or whether it has an odd-length cycle. The isBipartite operation determines whether the graph is bipartite. If so, the color operation determines a bipartition if not, the oddCycle operation determines a cycle with an odd number of edges. This implementation uses depth-first search. The constructor takes time proportional to V + E (in the worst case), where V is the number of vertices and E is the number of edges. Afterwards, the isBipartite and color operations take constant time the oddCycle operation takes time proportional to the length of the cycle. See BipartiteX for a nonrecursive version that uses breadth-first search. """ class UnsupportedOperationException(Exception): pass def __init__(self, G): """ Determines whether an undirected graph is bipartite and finds either a bipartition or an odd-length cycle. :param G: the graph """ self._is_bipartite = True # is the graph bipartite? self._color = [ False ] * G.V() # color[v] gives vertices on one side of bipartition self._marked = [ False ] * G.V() # marked[v] = True if v has been visited in DFS self._edge_to = [0] * G.V() # edgeTo[v] = last edge on path to v self._cycle = None # odd-length cycle for v in range(G.V()): if not self._marked[v]: self._dfs(G, v) assert self._check(G) def _dfs(self, G, v): self._marked[v] = True for w in G.adj(v): # short circuit if odd-length cycle found if self._cycle is not None: return # found uncolored vertex, so recur if not self._marked[w]: self._edge_to[w] = v self._color[w] = not self._color[v] self._dfs(G, w) # if v-w create an odd-length cycle, find it elif self._color[w] == self._color[v]: self._is_bipartite = False self._cycle = Stack() self._cycle.push( w ) # don't need this unless you want to include start vertex twice x = v while x != w: self._cycle.push(x) x = self._edge_to[x] self._cycle.push(w) def is_bipartite(self): """ Returns True if the graph is bipartite. :returns: True if the graph is bipartite False otherwise """ return self._is_bipartite def color(self, v): """ Returns the side of the bipartite that vertex v is on. :param v: the vertex :returns: the side of the bipartition that vertex v is on two vertices are in the same side of the bipartition if and only if they have the same color :raises IllegalArgumentException: unless 0 <= v < V :raises UnsupportedOperationException: if this method is called when the graph is not bipartite """ self._validateVertex(v) if not self._is_bipartite: raise Bipartite.UnsupportedOperationException( "graph is not bipartite") return self._color[v] def odd_cycle(self): """ Returns an odd-length cycle if the graph is not bipartite, and None otherwise. :returns: an odd-length cycle if the graph is not bipartite (and hence has an odd-length cycle), and None otherwise """ return self._cycle def _check(self, G): # graph is bipartite if self._is_bipartite: for v in range(G.V()): for w in G.adj(v): if self._color[v] == self._color[w]: error = "edge {}-{} with {} and {} in same side of bipartition\n".format( v, w, v, w) print(error, file=sys.stderr) return False # graph has an odd-length cycle else: # verify cycle first = -1 last = -1 for v in self.odd_cycle(): if first == -1: first = v last = v if first != last: error = "cycle begins with {} and ends with {}\n".format( first, last) print(error, file=sys.stderr) return False return True def _validateVertex(self, v): # raise an ValueError unless 0 <= v < V V = len(self._marked) if v < 0 or v >= V: raise ValueError("vertex {} is not between 0 and {}".format( v, V - 1))
def evaluate(): ops = Stack() vals = Stack() while not stdio.isEmpty(): # Read token, push if operator s = stdio.readString() if s == "(": pass elif s == "+": ops.push(s) elif s == "-": ops.push(s) elif s == "*": ops.push(s) elif s == "/": ops.push(s) elif s == "sqrt": ops.push(s) elif s == ")": # Pop, evaluate and push result if token is ")" op = ops.pop() v = vals.pop() if op == "+": v = vals.pop() + v elif op == "-": v = vals.pop() - v elif op == "*": v = vals.pop() * v elif op == "/": v = vals.pop() / v elif op == "sqrt": v = math.sqrt(v) vals.push(v) else: vals.push(float(s)) stdio.writeln(vals.pop())
class EdgeWeightedDirectedCycle: """ Determines whether the edge-weighted digraph G has a directed cycle and, if so, finds such a cycle. :param G the edge-weighted digraph """ def __init__(self, G): self._marked = [False] * G.V() # marked[v] = has vertex v been marked? self._edgeTo = [ None ] * G.V() # edgeTo[v] = previous DirectedEdge on path to v self._onStack = [False] * G.V() # onStack[v] = is vertex on the stack? self._cycle = None # directed cycle (or None if no such cycle) for v in range(G.V()): if not self._marked[v]: self._dfs(G, v) # check that digraph has a cycle assert self._check() # check that algorithm computes either the topological order or finds a directed cycle def _dfs(self, G, v): self._onStack[v] = True self._marked[v] = True for e in G.adj(v): w = e.to_vertex() # short circuit if directed cycle found if self._cycle is not None: return # found new vertex, so recur elif not self._marked[w]: self._edgeTo[w] = e self._dfs(G, w) # trace back directed cycle elif self._onStack[w]: self._cycle = Stack() f = e while f.from_vertex() != w: self._cycle.push(f) f = self._edgeTo[f.from_vertex()] self._cycle.push(f) return self._onStack[v] = False # Does the edge-weighted digraph have a directed cycle? # @return True if the edge-weighted digraph has a directed cycle, # False otherwise def has_cycle(self): return self._cycle is not None # Returns a directed cycle if the edge-weighted digraph has a directed cycle, # and None otherwise. # @return a directed cycle (as an iterable) if the edge-weighted digraph # has a directed cycle, and None otherwise def cycle(self): return self._cycle # certify that digraph is either acyclic or has a directed cycle def _check(self): # edge-weighted digraph is cyclic if self.has_cycle(): # verify cycle first = None last = None for e in self.cycle(): if first is None: first = e if last is not None: if last.to_vertex() != e.from_vertex(): print("cycle edges {} and {} not incident".format( last, e)) return False last = e if last.to_vertex() != first.from_vertex(): print("cycle edges {} and {} not incident".format(last, first)) return False return True