in src/dachshund/algorithms/coreness.rs [179:251]
fn _get_k_trusses(
&self,
k: usize,
ignore_nodes: &FxHashSet<NodeId>,
) -> (Vec<OrderedEdgeSet>, HashSet<OrderedNodeSet>) {
let mut neighbors: HashMap<NodeId, HashSet<NodeId>> = HashMap::new();
let mut edges: OrderedEdgeSet = BTreeSet::new();
for node in self.get_nodes_iter() {
// [TODO] This step is unncessary now.
neighbors.insert(
node.get_id(),
HashSet::from_iter(
node.get_edges()
.map(|x| x.get_neighbor_id())
.filter(|x| !ignore_nodes.contains(x)),
),
);
for e in node.get_edges() {
let id_pair: (NodeId, NodeId);
let node_id = node.get_id();
let neighbor_id = e.get_neighbor_id();
if node_id < neighbor_id {
id_pair = (node_id, neighbor_id);
} else {
id_pair = (neighbor_id, node_id);
}
edges.insert(id_pair);
}
}
let mut changes = true;
let mut ignore_edges: HashSet<(NodeId, NodeId)> = HashSet::new();
while changes {
changes = false;
let mut to_remove: Vec<(NodeId, NodeId)> = Vec::new();
for (id1, id2) in &edges {
let n1 = &neighbors[&id1];
let n2 = &neighbors[&id2];
let intersection = n1.intersection(n2);
if intersection.count() < k - 2 {
to_remove.push((*id1, *id2));
neighbors.get_mut(id1).unwrap().remove(id2);
neighbors.get_mut(id2).unwrap().remove(id1);
}
}
for e in &to_remove {
changes = true;
edges.remove(&e);
ignore_edges.insert(*e);
}
}
let (components, num_components) =
self._get_connected_components_membership(None, Some(&ignore_edges));
let mut trusses: Vec<OrderedEdgeSet> = vec![BTreeSet::new(); num_components];
for (id, idx) in &components {
// reusing the neighbors sets from above
for nid in &neighbors[&id] {
// will only return (lesser_id, greater_id) for an UndirectedGraph
if components[nid] == *idx && id < nid {
let eid = (*id, *nid);
if !ignore_edges.contains(&eid) && edges.contains(&eid) {
trusses[*idx].insert(eid);
}
}
}
}
let filtered_trusses: Vec<OrderedEdgeSet> =
trusses.into_iter().filter(|x| !x.is_empty()).collect();
let truss_nodes = filtered_trusses
.iter()
.map(|y| BTreeSet::from_iter(y.iter().map(|x| x.0).chain(y.iter().map(|x| x.1))))
.collect::<HashSet<OrderedNodeSet>>();
(filtered_trusses, truss_nodes)
}