| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Support for graphs.""" | 5 """Support for graphs.""" |
| 6 | 6 |
| 7 import collections | 7 import collections |
| 8 | 8 |
| 9 | 9 |
| 10 class Node(object): | 10 class Node(object): |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 A graph is identified by a list of nodes and a list of edges. It does not need | 37 A graph is identified by a list of nodes and a list of edges. It does not need |
| 38 to be acyclic, but then some methods will fail. | 38 to be acyclic, but then some methods will fail. |
| 39 """ | 39 """ |
| 40 def __init__(self, nodes, edges): | 40 def __init__(self, nodes, edges): |
| 41 """Builds a graph from a set of node and edges. | 41 """Builds a graph from a set of node and edges. |
| 42 | 42 |
| 43 Note that the edges referencing a node not in the provided list are dropped. | 43 Note that the edges referencing a node not in the provided list are dropped. |
| 44 | 44 |
| 45 Args: | 45 Args: |
| 46 nodes: ([Node]) List of nodes. | 46 nodes: ([Node]) Sequence of Nodes. |
| 47 edges: ([Edge]) List of Edges. | 47 edges: ([Edge]) Sequence of Edges. |
| 48 """ | 48 """ |
| 49 assert all(isinstance(node, Node) for node in nodes) | |
| 50 assert all(isinstance(edge, Edge) for edge in edges) | |
| 51 self._nodes = set(nodes) | 49 self._nodes = set(nodes) |
| 52 self._edges = set(filter( | 50 self._edges = set(filter( |
| 53 lambda e: e.from_node in self._nodes and e.to_node in self._nodes, | 51 lambda e: e.from_node in self._nodes and e.to_node in self._nodes, |
| 54 edges)) | 52 edges)) |
| 53 assert all(isinstance(node, Node) for node in self._nodes) |
| 54 assert all(isinstance(edge, Edge) for edge in self._edges) |
| 55 self._in_edges = {n: [] for n in self._nodes} | 55 self._in_edges = {n: [] for n in self._nodes} |
| 56 self._out_edges = {n: [] for n in self._nodes} | 56 self._out_edges = {n: [] for n in self._nodes} |
| 57 for edge in self._edges: | 57 for edge in self._edges: |
| 58 self._out_edges[edge.from_node].append(edge) | 58 self._out_edges[edge.from_node].append(edge) |
| 59 self._in_edges[edge.to_node].append(edge) | 59 self._in_edges[edge.to_node].append(edge) |
| 60 | 60 |
| 61 def OutEdges(self, node): | 61 def OutEdges(self, node): |
| 62 """Returns a list of edges starting from a node. | 62 """Returns a list of edges starting from a node. |
| 63 """ | 63 """ |
| 64 return self._out_edges[node] | 64 return self._out_edges[node] |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 node = (i for i in self._nodes if costs[i] == max_cost).next() | 166 node = (i for i in self._nodes if costs[i] == max_cost).next() |
| 167 path_list.append(node) | 167 path_list.append(node) |
| 168 while self.InEdges(node): | 168 while self.InEdges(node): |
| 169 predecessors = [e.from_node for e in self.InEdges(node)] | 169 predecessors = [e.from_node for e in self.InEdges(node)] |
| 170 node = reduce( | 170 node = reduce( |
| 171 lambda costliest_node, next_node: | 171 lambda costliest_node, next_node: |
| 172 next_node if costs[next_node] > costs[costliest_node] | 172 next_node if costs[next_node] > costs[costliest_node] |
| 173 else costliest_node, predecessors) | 173 else costliest_node, predecessors) |
| 174 path_list.insert(0, node) | 174 path_list.insert(0, node) |
| 175 return max_cost | 175 return max_cost |
| OLD | NEW |