public void GenerateRandomGraph_GeneratesAcyclcGraph() { var settings = new RandomGraphSettings(); var graph = GraphHelper.GenerateRandomGraph(settings); Assert.AreEqual(false, GraphHelper.HasCycles(graph)); }
private static void SetNodesLayers(List <Node> graph, RandomGraphSettings settings) { var startNode = graph.GetRandomElement(); startNode.Layer = 0; var nonStartNodes = graph.Except(new[] { startNode }).ToList(); foreach (var node in nonStartNodes) { node.Layer = Random.Next(1, settings.LayerCount); } BalanceLayers(graph, settings); }
public void GenerateRandomGraph_GeneratesChainIfNodeCountEqualsLayerCount() { var settings = new RandomGraphSettings { NodeCount = 10, LayerCount = 10 }; var graph = GraphHelper.GenerateRandomGraph(settings); var orderedGraph = graph.OrderBy(n => n.Layer).ToList(); for (var i = 0; i < settings.NodeCount; ++i) { Assert.AreEqual(i, orderedGraph[i].Layer); } }
public void GenerateRandomGraph_GeneratesGraphsWithCorrectParams() { var settings = new RandomGraphSettings { NodeCount = 10, LayerCount = 4, MaxNodeDegree = 5, MinNodeDegree = 2 }; var graph = GraphHelper.GenerateRandomGraph(settings); var distinctLayersCount = graph.GetLayerCount(); var minNodeDegree = graph.Where(n => n.Layer < distinctLayersCount - 1).Min(n => n.Degree); Assert.AreEqual(settings.LayerCount, distinctLayersCount); Assert.IsTrue(minNodeDegree >= settings.MinNodeDegree); }
private static void BalanceLayers(IReadOnlyCollection <Node> graph, RandomGraphSettings settings) { var emptyLayers = Enumerable .Range(1, settings.LayerCount - 1) .Where(layer => graph.All(n => n.Layer != layer)) .ToList(); foreach (var emptyLayer in emptyLayers) { var largeLayers = Enumerable .Range(1, settings.LayerCount - 1) .Where(layer => graph.Count(n => n.Layer == layer) > 1) .ToList(); var donorLayer = largeLayers.GetRandomElement(); graph.First(n => n.Layer == donorLayer).Layer = emptyLayer; } }
private static void AdjustHeights(List <Node> nodes, RandomGraphSettings settings) => nodes.ForEach(n => n.Height += n.NextNodes.Count * settings.DegreeHeightBonus);
public static List <Node> GenerateRandomGraph(RandomGraphSettings settings) { var graph = new List <Node>(); for (var i = 0; i < settings.NodeCount; ++i) { graph.Add(new Node { Height = NextDouble(settings.MinNodeHeight, settings.MaxNodeHeight), Width = NextDouble(settings.MinNodeWidth, settings.MaxNodeWidth), }); } SetNodesLayers(graph, settings); PrintDebugInfo(graph); for (var i = 0; i < settings.LayerCount - 1; ++i) { var layer = graph.Where(n => n.Layer == i).ToList(); var nextLayer = graph.Where(n => n.Layer == i + 1).ToList(); var prevLayers = graph.Where(n => n.Layer <= i && n.Layer > 0).ToList(); foreach (var node in layer) { var nextNodeCount = Math.Max(Random.Next(settings.MinNodeDegree, settings.MaxNodeDegree + 1), nextLayer.Count); var nextLayerNodes = prevLayers.Any() ? Random.Next(1, nextNodeCount + 1) : nextNodeCount; for (var j = 0; j < nextLayerNodes; ++j) { node.NextNodes.Add(nextLayer.GetRandomElement()); } var prevNodes = nextNodeCount - nextLayerNodes; var prevNodesConnected = 0; var attempts = 0; while (prevNodesConnected < prevNodes && attempts < 10 * prevNodes) { var prevNode = prevLayers.GetRandomElement(); if (TryAddBackConnection(node, prevNode, graph)) { prevNodesConnected++; } attempts++; } for (var j = 0; j < prevNodes - prevNodesConnected; ++j) { node.NextNodes.Add(nextLayer.GetRandomElement()); } } } EnsureGraphIsConnected(graph); PrintDebugInfo(graph); SetPreviousNodes(graph); AdjustHeights(graph, settings); LayerHelper.SetLayers(graph); LayerHelper.SetCoLayers(graph); PrintDebugInfo(graph); return(graph); }