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 |