1+ #include " directed_graph.h"
2+ #include " ../common/utils.h"
3+
4+ DiGraph::DiGraph (): Graph() {
5+
6+ }
7+
8+ py::object DiGraph__init__ (py::tuple args, py::dict kwargs) {
9+ py::object MappingProxyType = py::import (" types" ).attr (" MappingProxyType" );
10+ py::object self = args[0 ];
11+ self.attr (" __init__" )();
12+ DiGraph& self_ = py::extract<DiGraph&>(self);
13+ py::dict graph_attr = kwargs;
14+ self_.graph .update (graph_attr);
15+ self_.nodes_cache = MappingProxyType (py::dict ());
16+ self_.adj_cache = MappingProxyType (py::dict ());
17+ return py::object ();
18+ }
19+
20+ py::object DiGraph_out_degree (py::object self, py::object weight) {
21+ py::dict degree = py::dict ();
22+ py::list edges = py::extract<py::list>(self.attr (" edges" ));
23+ py::object u, v;
24+ py::dict d;
25+ for (int i = 0 ;i < py::len (edges);i++) {
26+ py::tuple edge = py::extract<py::tuple>(edges[i]);
27+ u = edge[0 ];
28+ v = edge[1 ];
29+ d = py::extract<py::dict>(edge[2 ]);
30+ if (degree.contains (u)) {
31+ degree[u] += d.get (weight, 1 );
32+ }
33+ else {
34+ degree[u] = d.get (weight, 1 );
35+ }
36+ }
37+ py::list nodes = py::list (self.attr (" nodes" ));
38+ for (int i = 0 ;i < py::len (nodes);i++) {
39+ py::object node = nodes[i];
40+ if (!degree.contains (node)) {
41+ degree[node] = 0 ;
42+ }
43+ }
44+ return degree;
45+ }
46+
47+ py::object DiGraph_in_degree (py::object self, py::object weight) {
48+ py::dict degree = py::dict ();
49+ py::list edges = py::extract<py::list>(self.attr (" edges" ));
50+ py::object u, v;
51+ py::dict d;
52+ for (int i = 0 ;i < py::len (edges);i++) {
53+ py::tuple edge = py::extract<py::tuple>(edges[i]);
54+ u = edge[0 ];
55+ v = edge[1 ];
56+ d = py::extract<py::dict>(edge[2 ]);
57+ if (degree.contains (v)) {
58+ degree[v] += d.get (weight, 1 );
59+ }
60+ else {
61+ degree[v] = d.get (weight, 1 );
62+ }
63+ }
64+ py::list nodes = py::list (self.attr (" nodes" ));
65+ for (int i = 0 ;i < py::len (nodes);i++) {
66+ py::object node = nodes[i];
67+ if (!degree.contains (node)) {
68+ degree[node] = 0 ;
69+ }
70+ }
71+ return degree;
72+ }
73+
74+ py::object DiGraph_degree (py::object self, py::object weight) {
75+ py::dict degree = py::dict ();
76+ py::dict out_degree = py::extract<py::dict>(self.attr (" out_degree" )(weight));
77+ py::dict in_degree = py::extract<py::dict>(self.attr (" in_degree" )(weight));
78+ py::list nodes = py::list (self.attr (" nodes" ));
79+ for (int i = 0 ;i < py::len (nodes);i++) {
80+ py::object u = nodes[i];
81+ degree[u] = out_degree[u] + in_degree[u];
82+ }
83+ return degree;
84+ }
85+
86+ py::object DiGraph_size (py::object self, py::object weight) {
87+ py::dict out_degree = py::extract<py::dict>(self.attr (" out_degree" )(weight));
88+ py::object s = py_sum (out_degree.values ());
89+ return (weight == py::object ()) ? py::object (py::extract<int >(s)) : s;
90+ }
91+
92+ py::object DiGraph_number_of_edges (py::object self, py::object u, py::object v) {
93+ if (u == py::object ()) {
94+ return self.attr (" size" )();
95+ }
96+ Graph& G = py::extract<Graph&>(self);
97+ node_t u_id = py::extract<node_t >(G.node_to_id [u]);
98+ node_t v_id = py::extract<node_t >(G.node_to_id .get (v, -1 ));
99+ return py::object (int (v != -1 && G.adj [u_id].count (v_id)));
100+ }
0 commit comments