/// <summary> /// Generates random network with 'n' actors, 'l' layers. /// </summary> /// <param name="n">Number of actors.</param> /// <param name="l">Number of layers.</param> /// <param name="p">Probability of an edge.</param> /// <returns>Generated network.</returns> public Network Generate(int n, int l, double p) { if (p > 1.0 || p < 0.0) { throw new ArgumentOutOfRangeException("Probabilty must between 0.0 and 1.0."); } if (n <= 0) { throw new ArgumentOutOfRangeException("Number of nodes must be greater than zero."); } if (l <= 0) { throw new ArgumentOutOfRangeException("Number of layers must be greater than zero."); } var singleLayer = GenerateSingleLayer(n, p); var actors = singleLayer.Actors; var layers = InitLayers(l); var actorToLayer = ActorToLayer(actors, layers); var multiLayer = new Network(layers, actors); foreach (var edge in singleLayer.FirstLayer.Edges) { var f = edge.From; var t = edge.To; var lf = actorToLayer[f]; var lt = actorToLayer[t]; if (lf == lt) { lf.Edges.Add(edge); } else { var interLayer = new InterLayerEdge { From = f, To = t, LayerFrom = lf, LayerTo = lt, Weight = edge.Weight, }; multiLayer.InterLayerEdges.Add(interLayer); } } return(multiLayer); }
/// <summary> /// Creates network from a string in edgelist format. /// Edgelist must be in following format: /// actor_from layer_from actor_to layer_to weight. /// It can also include metadata in following format: /// # Actors /// actor_idx actor_name /// # Layers /// layer_idx layer_name. /// </summary> /// <param name="input">Input string in edgelist format.</param> /// <returns>Read network.</returns> public Network FromString(string input) { var idCounter = 1; var actors = new Dictionary <string, Actor>(); var layers = new Dictionary <string, Layer>(); var rows = new List <EdgeListRow>(); var lines = input.Split('\n'); for (var i = 0; i < lines.Length; i++) { if (i == lines.Length - 1 && string.IsNullOrWhiteSpace(lines[i])) { break; } if (lines[i].StartsWith("# Actors")) { i++; for (; i < lines.Length; i++) { if (lines[i].StartsWith("# Layers")) { break; } var values = lines[i].Trim().Split(" "); if (i == lines.Length - 1 && string.IsNullOrWhiteSpace(lines[i])) { break; } if (values.Length != 2) { throw new ArgumentException("Invalid edgelist actors metadata."); } var a = values[0]; var n = values[1]; if (actors.ContainsKey(a)) { actors[a].Name = n; } else { actors.Add(a, new Actor(idCounter++, n)); } } i++; for (; i < lines.Length; i++) { if (lines[i].StartsWith("# Layers")) { break; } var values = lines[i].Trim().Split(" "); if (i == lines.Length - 1 && string.IsNullOrWhiteSpace(lines[i])) { break; } if (values.Length != 2) { throw new ArgumentException("Invalid edgelist layers metadata."); } var l = values[0]; var n = values[1]; if (layers.ContainsKey(l)) { layers[l].Name = n; } else { layers.Add(l, new Layer() { Name = n }); } } } else { var values = lines[i].Trim().Split(" "); if (values.Length != 5) { throw new ArgumentException("Invalid edgelist."); } var a1 = values[0]; var l1 = values[1]; var a2 = values[2]; var l2 = values[3]; var w = values[4]; if (!double.TryParse(w, out _)) { throw new ArgumentException("Invalid weight."); } var row = new EdgeListRow { Actor1 = a1, Layer1 = l1, Actor2 = a2, Layer2 = l2, Weight = w, }; if (!actors.ContainsKey(a1)) { actors.Add(a1, new Actor { Name = a1 }); } if (!actors.ContainsKey(a2)) { actors.Add(a2, new Actor { Name = a2 }); } if (!layers.ContainsKey(l1)) { layers.Add(l1, new Layer { Name = l1 }); } if (!layers.ContainsKey(l2)) { layers.Add(l2, new Layer { Name = l2 }); } rows.Add(row); } } var network = new Network(); foreach (var actor in actors) { network.Actors.Add(actor.Value); } foreach (var layer in layers) { network.Layers.Add(layer.Value); } foreach (var row in rows) { var a1 = actors[row.Actor1]; var a2 = actors[row.Actor2]; var l1 = layers[row.Layer1]; var l2 = layers[row.Layer2]; var w = double.Parse(row.Weight); if (l1 == l2) { var edge = new Edge { From = a1, To = a2, Weight = w, }; l1.Edges.Add(edge); } else { var edge = new InterLayerEdge { From = a1, To = a2, LayerFrom = l1, LayerTo = l2, Weight = w, }; network.InterLayerEdges.Add(edge); } } return(network); }