/// <summary> /// Returns clustering coefficient of the given node. /// </summary> /// <param name="mnet">Multilayer network model.</param> /// <param name="node">Node to calculate clustering coefficient on.</param> /// <returns>Clustering coefficient of the given node.</returns> public double ClusteringCoefficient(MultilayerNetwork mnet, Node node) { // Edges between neighbors. // How well connected are they. double edgesCount = 0; // Get all neighbors of the node. var neighbors = mnet.Neighbors(node, EdgeMode.InOut); // Degree of the node. var neighborsCount = neighbors.Count; if (neighborsCount <= 1) { return(0); } // Go through all neighbors of our node. // And check how well connected they are between each other. foreach (var n1 in neighbors) { foreach (var n2 in neighbors) { if (n1 == n2) { continue; } if (mnet.GetEdge(n1, n2) != null) { edgesCount++; } } } return((edgesCount) / (neighborsCount * (neighborsCount - 1))); }
// Possible to sort nodes. // and in each loop go only through nodes with higher degree and higher id. private double ClusteringCoefficient_TODO(MultilayerNetwork mnet, Layer layer) { // 3 x Number of triangles / number of connected triplets of vertices // number of closed triplets / number of connected triplets of vertices var triangleCount = 0; double tripletsCount = 0; var nodes = mnet.NodesByLayer[layer.Id]; // Count the triangles. foreach (var v in nodes) { foreach (var u in nodes) { if (v == u || mnet.GetEdge(v, u) == null) { continue; } foreach (var w in nodes) { if (u == w || mnet.GetEdge(v, w) == null) { continue; } // Check for the final path. if (mnet.GetEdge(u, w) != null) { triangleCount++; } } } } var edgesCount = mnet.EdgesByLayerPair[layer.Id][layer.Id].Count; return((3 * triangleCount) / tripletsCount); }
/// <summary> /// Flatten layers into single layer. /// </summary> /// <param name="mnet">Multilayer network.</param> /// <param name="newLayerName">Name of the new layer.</param> /// <param name="layers">Layers to flatten.</param> /// <param name="forceDirected">True if new edges should be directed, false if not.</param> /// <param name="forceActors">True if all actors should be on the new layer, false if not.</param> /// <returns>Flattened layer.</returns> public Layer FlattenUnweighted(MultilayerNetwork mnet, string newLayerName, HashSet <Layer> layers, bool forceDirected = false, bool forceActors = false) { var newLayer = createLayer(mnet, newLayerName, layers, forceDirected, forceActors); var directed = mnet.IsDirected(newLayer, newLayer); foreach (var layer1 in layers) { foreach (var layer2 in layers) { foreach (var edge in mnet.GetEdges(layer1, layer2)) { var node1 = mnet.GetNode(edge.V1.Actor, newLayer); var node2 = mnet.GetNode(edge.V2.Actor, newLayer); var newEdge = mnet.GetEdge(node1, node2); if (newEdge == null) { newEdge = mnet.AddEdge(node1, node2); } // If new layer is directed, undirected edges must be added twice in both directions. if (directed && edge.Directionality == EdgeDirectionality.Undirected) { newEdge = mnet.GetEdge(node2, node1); if (newEdge == null) { newEdge = mnet.AddEdge(node2, node1); } } } } } return(newLayer); }