1use std::cmp::Ordering;
2
3pub mod csr {
4
5 use crate::csr::CSR;
6
7 pub fn count(graph: &CSR) -> usize{
8 let mut cnt = 0usize;
9 for u in 0..graph.n_nodes() {
10 for v in graph.neighbors(u){
11 cnt += count_intersect(u, *v, graph);
12 }
13 }
14 return cnt;
15 }
16
17 pub fn count_intersect(u: usize, v: usize, graph: &CSR) -> usize {
18 let mut cnt = 0usize;
19
20 let mut uiter = graph.neighbors(u).iter();
21 let mut viter = graph.neighbors(v).iter();
22
23 let mut un = match uiter.next() {
24 Some(x) => x,
25 None => return cnt
26 };
27
28 let mut vn = match viter.next() {
29 Some(x) => x,
30 None => return cnt
31 };
32
33 loop{
34 if un < vn {
35 un = match uiter.next() {
36 Some(x) => x,
37 None => return cnt
38 }
39 }
40 else if un > vn {
41 vn = match viter.next() {
42 Some(x) => x,
43 None => return cnt
44 }
45 }
46 else {
47 cnt += 1;
48
49 un = match uiter.next() {
50 Some(x) => x,
51 None => return cnt
52 };
53 vn = match viter.next() {
54 Some(x) => x,
55 None => return cnt
56 };
57 }
58 }
59 }
60}
61
62pub mod csbv {
63
64 use crate::csbv::CSBV;
65
66 pub fn count(graph: &CSBV) -> usize{
67
68 let mut cnt = 0usize;
69
70 for u in 0..graph.n_nodes() {
71 for v in graph.neighbor_iter(u) {
72 cnt += count_intersect(u, v, &graph);
73 }
74 }
75 return cnt;
76 }
77
78 pub fn count_intersect(u: usize, v: usize, graph: &CSBV) -> usize{
79 let mut cnt = 0usize;
80
81 let mut uiter = graph.block_iter(u);
82 let mut viter = graph.block_iter(v);
83
84 let (mut un, mut un_bits) = match uiter.next() {
85 Some(x) => x,
86 None => return cnt
87 };
88
89 let (mut vn, mut vn_bits) = match viter.next() {
90 Some(x) => x,
91 None => return cnt
92 };
93
94 loop{
95 if un < vn {
96 (un, un_bits) = match uiter.next() {
97 Some(x) => x,
98 None => return cnt
99 }
100 }
101 else if un > vn {
102 (vn, vn_bits) = match viter.next() {
103 Some(x) => x,
104 None => return cnt
105 }
106 }
107 else {
108 cnt += (un_bits & vn_bits).count_ones() as usize;
109
110 (un, un_bits) = match uiter.next() {
111 Some(x) => x,
112 None => return cnt
113 };
114 (vn, vn_bits) = match viter.next() {
115 Some(x) => x,
116 None => return cnt
117 };
118 }
119 }
120
121 }
122
123}
124
125
126pub fn count_total(adj: Vec<Vec<usize>>) -> usize{
127 let mut cnt = 0usize;
128 for adj_u in adj.iter(){
129 for v in adj_u{
130 cnt += count_intersect_btw_sorted(adj_u, &adj[*v]);
131 }
132 }
133 return cnt;
134}
135
136fn count_intersect_btw_sorted(adj_u: &Vec<usize>, adj_v: &Vec<usize>) -> usize{
137 let mut iter_u = adj_u.iter();
138 let mut iter_v = adj_v.iter();
139 let mut un = match iter_u.next() { Some(un) => un, None => return 0 };
140 let mut vn = match iter_v.next() { Some(vn) => vn, None => return 0 };
141
142 let mut cnt = 0usize;
143
144 loop {
145 match un.cmp(vn){
146 Ordering::Less => {
147 un = match iter_u.next() { Some(un) => un, None => return cnt };
148 }
149 Ordering::Greater => {
150 vn = match iter_v.next() { Some(vn) => vn, None => return cnt };
151 }
152 Ordering::Equal => {
153 cnt += 1;
154 un = match iter_u.next() { Some(un) => un, None => return cnt };
155 vn = match iter_v.next() { Some(vn) => vn, None => return cnt };
156 }
157 };
158 }
159}