|
| 1 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 2 | +// not use this file except in compliance with the License. You may obtain |
| 3 | +// a copy of the License at |
| 4 | +// |
| 5 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | +// |
| 7 | +// Unless required by applicable law or agreed to in writing, software |
| 8 | +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 9 | +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 10 | +// License for the specific language governing permissions and limitations |
| 11 | +// under the License. |
| 12 | + |
| 13 | +use std::hash::Hash; |
| 14 | + |
| 15 | +use petgraph::data::{Build, Create}; |
| 16 | +use petgraph::visit::{Data, NodeIndexable}; |
| 17 | + |
| 18 | +/// Generates Zachary's Karate Club graph. |
| 19 | +/// |
| 20 | +/// Zachary's Karate Club graph is a well-known social network that represents |
| 21 | +/// the relations between 34 members of a karate club. |
| 22 | +/// Arguments: |
| 23 | +/// |
| 24 | +/// * `default_node_weight` - A callable that will receive a boolean, indicating |
| 25 | +/// if a node is part of Mr Hi's faction (True) or the Officer's faction (false). |
| 26 | +/// It shoudl return the node weight according to the desired type. |
| 27 | +/// * `default_edge_weight` - A callable that will receive the integer representing |
| 28 | +/// the strenght of the relation between two nodes. It should return the edge |
| 29 | +/// weight according to the desired type. |
| 30 | +/// |
| 31 | +pub fn karate_club_graph<G, T, F, H, M>(mut default_node_weight: F, mut default_edge_weight: H) -> G |
| 32 | +where |
| 33 | + G: Build + Create + Data<NodeWeight = T, EdgeWeight = M> + NodeIndexable, |
| 34 | + F: FnMut(bool) -> T, |
| 35 | + H: FnMut(usize) -> M, |
| 36 | + G::NodeId: Eq + Hash, |
| 37 | +{ |
| 38 | + const N: usize = 34; |
| 39 | + const M: usize = 78; |
| 40 | + let mr_hi_members: [u8; 17] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 16, 17, 19, 21]; |
| 41 | + let membership: std::collections::HashSet<u8> = mr_hi_members.into_iter().collect(); |
| 42 | + |
| 43 | + let adjacency_list: Vec<Vec<(usize, usize)>> = vec![ |
| 44 | + vec![], |
| 45 | + vec![(0, 4)], |
| 46 | + vec![(0, 5), (1, 6)], |
| 47 | + vec![(0, 3), (1, 3), (2, 3)], |
| 48 | + vec![(0, 3)], |
| 49 | + vec![(0, 3)], |
| 50 | + vec![(0, 3), (4, 2), (5, 5)], |
| 51 | + vec![(0, 2), (1, 4), (2, 4), (3, 3)], |
| 52 | + vec![(0, 2), (2, 5)], |
| 53 | + vec![(2, 1)], |
| 54 | + vec![(0, 2), (4, 3), (5, 3)], |
| 55 | + vec![(0, 3)], |
| 56 | + vec![(0, 1), (3, 3)], |
| 57 | + vec![(0, 3), (1, 5), (2, 3), (3, 3)], |
| 58 | + vec![], |
| 59 | + vec![], |
| 60 | + vec![(5, 3), (6, 3)], |
| 61 | + vec![(0, 2), (1, 1)], |
| 62 | + vec![], |
| 63 | + vec![(0, 2), (1, 2)], |
| 64 | + vec![], |
| 65 | + vec![(0, 2), (1, 2)], |
| 66 | + vec![], |
| 67 | + vec![], |
| 68 | + vec![], |
| 69 | + vec![(23, 5), (24, 2)], |
| 70 | + vec![], |
| 71 | + vec![(2, 2), (23, 4), (24, 3)], |
| 72 | + vec![(2, 2)], |
| 73 | + vec![(23, 3), (26, 4)], |
| 74 | + vec![(1, 2), (8, 3)], |
| 75 | + vec![(0, 2), (24, 2), (25, 7), (28, 2)], |
| 76 | + vec![ |
| 77 | + (2, 2), |
| 78 | + (8, 3), |
| 79 | + (14, 3), |
| 80 | + (15, 3), |
| 81 | + (18, 1), |
| 82 | + (20, 3), |
| 83 | + (22, 2), |
| 84 | + (23, 5), |
| 85 | + (29, 4), |
| 86 | + (30, 3), |
| 87 | + (31, 4), |
| 88 | + ], |
| 89 | + vec![ |
| 90 | + (8, 4), |
| 91 | + (9, 2), |
| 92 | + (13, 3), |
| 93 | + (14, 2), |
| 94 | + (15, 4), |
| 95 | + (18, 2), |
| 96 | + (19, 1), |
| 97 | + (20, 1), |
| 98 | + (23, 4), |
| 99 | + (26, 2), |
| 100 | + (27, 4), |
| 101 | + (28, 2), |
| 102 | + (29, 2), |
| 103 | + (30, 3), |
| 104 | + (31, 4), |
| 105 | + (32, 5), |
| 106 | + (22, 3), |
| 107 | + ], |
| 108 | + ]; |
| 109 | + |
| 110 | + let mut graph = G::with_capacity(N, M); |
| 111 | + |
| 112 | + let mut node_indices = Vec::with_capacity(N); |
| 113 | + for (row, neighbors) in adjacency_list.into_iter().enumerate() { |
| 114 | + let node_id = graph.add_node(default_node_weight(membership.contains(&(row as u8)))); |
| 115 | + node_indices.push(node_id); |
| 116 | + |
| 117 | + for (neighbor, weight) in neighbors.into_iter() { |
| 118 | + graph.add_edge( |
| 119 | + node_indices[neighbor], |
| 120 | + node_indices[row], |
| 121 | + default_edge_weight(weight), |
| 122 | + ); |
| 123 | + } |
| 124 | + } |
| 125 | + graph |
| 126 | +} |
0 commit comments