/// <summary> /// Gets the linked nodes. /// </summary> /// <param name="centralNodeName">Name of the central node.</param> /// <param name="includeBtoALinks">if set to <c>true</c> [include bto a links].</param> /// <returns></returns> public freeGraphQueryResult GetLinkedNodes(String centralNodeName, Boolean includeBtoALinks = false, freeGraphQueryResult output = null) { if (output == null) { output = new freeGraphQueryResult(); } if (!Check()) { output.graphNotReady = true; return(output); } freeGraphNodeBase centralNode = GetNode(centralNodeName, true); output.queryNodes.Add(centralNode); if (!output.graphNodeNotFound) { output.AddRange(GetLinksBase(centralNodeName, false, 1, true)); output.includeBtoALinks = includeBtoALinks; if (output.includeBtoALinks) { output.AddRange(GetLinksBase(centralNodeName, true, 1, true)); } } return(output); }
/// <summary> /// Adds new node with <c>nameProposal</c> name or a modified version of the name - in order to have unique node name /// </summary> /// <param name="nameProposal">The name proposal.</param> /// <param name="weight">The weight.</param> /// <param name="type">The type.</param> /// <returns></returns> public freeGraphNodeBase AddNewNode(String nameProposal, Double weight = 1, Int32 type = 0) { Int32 c = 0; if (nameProposal.isNullOrEmpty()) { nameProposal = "Node" + nodes.Count(); } String proposal = nameProposal; Int32 nc = nodes.Count(x => x.name.StartsWith(nameProposal)); if (nc > 0) { c = nc; proposal = nameProposal + c.ToString("D3"); } while (ContainsNode(proposal, true)) { c++; proposal = nameProposal + c.ToString("D3"); } freeGraphNodeBase node = new freeGraphNodeBase(); node.name = proposal; node.weight = weight; node.type = type; nodes.Add(node); nodeDictionary.Add(proposal, node); return(node); }
/// <summary> /// Just clones the node and adds specified distance /// </summary> /// <param name="distanceIncrease">The distance increase.</param> /// <returns></returns> public freeGraphNodeBase GetQueryResultClone(Int32 distanceIncrease = 1) { freeGraphNodeBase node = new freeGraphNodeBase(); node.name = name; node.weight = weight; node.type = type; node.distance = distance + distanceIncrease; return(node); }
/// <summary> /// Adds new node into graph or sums weight of the specified and existing - and applies type that is greater /// </summary> /// <param name="link">The link.</param> public void AddNodeOrSum(freeGraphNodeBase node) { if (!ContainsNode(node.name)) { AddNode(node.name, node.weight, node.type); } else { var exLink = GetNode(node.name); //GetLink(link.nodeNameA, link.nodeNameB); if (exLink != null) { Double w = exLink.weight + node.weight; exLink.weight = w; exLink.type = Math.Max(exLink.type, node.type); } } }
/// <summary> /// Adds new node under <c>nodeName</c> or just returns if any existing /// </summary> /// <param name="nodeName">Name of the node.</param> /// <param name="weight">The weight.</param> /// <param name="type">The type.</param> /// <returns></returns> public freeGraphNodeBase AddNode(String nodeName, Double weight = 1, Int32 type = 0) { if (ContainsNode(nodeName, true)) { return(GetNode(nodeName, true)); } else { freeGraphNodeBase node = new freeGraphNodeBase(); node.name = nodeName; node.weight = weight; node.type = type; nodes.Add(node); nodeDictionary.Add(nodeName, node); return(node); } }
/// <summary> /// Gets the nodes. /// </summary> /// <param name="nodeNames">The node names.</param> /// <param name="skipCheck">if set to <c>true</c> [skip check].</param> /// <returns></returns> public List <freeGraphNodeBase> GetNodes(IEnumerable <String> nodeNames, Boolean skipCheck = false) { List <freeGraphNodeBase> queryNodes = new List <freeGraphNodeBase>(); if (!skipCheck) { Check(); } foreach (String nodeName in nodeNames) { freeGraphNodeBase node = GetNode(nodeName, true); if (node != null) { queryNodes.Add(node); } } return(queryNodes); }
public List <freeGraphNodeBase> GetLinkedNodesBase(String nodeName, Boolean BtoA = false, Int32 distanceCorrection = 0, Boolean cloneAndAdjustWeight = true) { List <freeGraphNodeBase> output = new List <freeGraphNodeBase>(); Double weightFactor = 1; if (cloneAndAdjustWeight == false) { if (BtoA) { if (linkedBtoADictionary.ContainsKey(nodeName)) { return(linkedBtoADictionary[nodeName]); } } else { if (linkedAtoBDictionary.ContainsKey(nodeName)) { return(linkedAtoBDictionary[nodeName]); } } } else { if (BtoA) { if (linkedBtoADictionary.ContainsKey(nodeName)) { foreach (var link in linkBtoADictionary[nodeName]) { freeGraphNodeBase nodeA = linkedBtoADictionary[nodeName].FirstOrDefault(x => x.name == link.nodeNameA); if (nodeA != null) { var n = nodeA.GetQueryResultClone(distanceCorrection); n.weight = n.weight * link.weight; output.Add(n); } } return(output); } } else { if (linkedAtoBDictionary.ContainsKey(nodeName)) { foreach (var link in linkAtoBDictionary[nodeName]) { freeGraphNodeBase nodeB = linkedAtoBDictionary[nodeName].FirstOrDefault(x => x.name == link.nodeNameB); if (nodeB != null) { var n = nodeB.GetQueryResultClone(distanceCorrection); n.weight = n.weight * link.weight; output.Add(n); } } return(output); } } } return(new List <freeGraphNodeBase>()); }
/// <summary> /// Pings the size of the graph by expanding from specified <c>pingSources</c> until number of reached nodes is increasing. <see cref="freeGraphPingType"/> /// </summary> /// <param name="graph">The graph that is probed.</param> /// <param name="pingSources">The ping sources - nodes to start ping expansion from.</param> /// <param name="bothDirections">if set to <c>true</c> if will expand trough both backward and forward links. Otherwise propagates forward</param> /// <param name="pingType">Type of the ping operation</param> /// <param name="pingLimit">The ping limit - after which the expansion will stop.</param> /// <returns>Value according to specified <c>pingType</c> or 0 on failure</returns> public static Double PingGraphSize(this freeGraph graph, IEnumerable <freeGraphNodeBase> pingSources, Boolean bothDirections, freeGraphPingType pingType, Int32 pingLimit = 100) { List <String> nodeNames = new List <string>(); List <String> centralNodes = new List <string>(); if (pingType == freeGraphPingType.unisonPingLength) { foreach (var p in pingSources) { centralNodes.Add(p.name); nodeNames.Add(p.name); } freeGraphNodeBase ps = pingSources.First(); var lst = new List <freeGraphNodeBase>(); // { ps }; lst.Add(ps); pingSources = lst; } List <Int32> pingResults = new List <int>(); List <Int32> pingedNodes = new List <int>(); foreach (var p in pingSources) { if (pingType != freeGraphPingType.unisonPingLength) { nodeNames = new List <string>(); centralNodes = new List <string>(); nodeNames.Add(p.name); centralNodes.Add(p.name); } Int32 pingSize = 1; Int32 c = 0; while (c < pingLimit) { var result = graph.GetLinkedNodes(centralNodes, 1, bothDirections); Int32 nCount = nodeNames.Count; foreach (var res in result) { centralNodes = new List <string>(); if (!nodeNames.Contains(res.name)) { nodeNames.Add(res.name); centralNodes.Add(res.name); } } if (nodeNames.Count > nCount) { pingSize++; } else if (nodeNames.Count == nCount) { break; } c++; if (pingSize > pingLimit) { break; } } pingResults.Add(pingSize); pingedNodes.Add(nodeNames.Count); } if (pingResults.Count > 0) { switch (pingType) { case freeGraphPingType.averagePingLength: return(pingResults.Average()); case freeGraphPingType.maximumPingLength: return(pingResults.Max()); case freeGraphPingType.unisonPingLength: return(pingResults.Max()); break; case freeGraphPingType.numberOfPingedNodes: return(nodeNames.Count); break; } } return(0); }
/// <summary> /// Pings the size of the graph by expanding from specified <c>pingSources</c> until number of reached nodes is increasing. <see cref="freeGraphPingType" /> /// </summary> /// <param name="graph">The graph that is probed.</param> /// <param name="pingSource">The ping source.</param> /// <param name="bothDirections">if set to <c>true</c> if will expand trough both backward and forward links</param> /// <param name="pingType">Type of the ping operation</param> /// <param name="pingLimit">The ping limit - after which the expansion will stop.</param> /// <returns> /// Value according to specified <c>pingType</c> or 0 on failure /// </returns> public static Double PingGraphSize(this freeGraph graph, freeGraphNodeBase pingSource, Boolean bothDirections, freeGraphPingType pingType, Int32 pingLimit = 100) { return(PingGraphSize(graph, new List <freeGraphNodeBase> { pingSource }, bothDirections, pingType, pingLimit)); }