/// <summary> /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition. /// </summary> public bool IsNetworkCyclicInternal(INetworkDefinition networkDef) { // Clear any existing state (allow reuse of this class). _ancestorNodeSet.Clear(); _visitedNodeSet.Clear(); // Get and store connectivity data for the network. _networkConnectivityData = networkDef.GetConnectivityData(); // Loop over all nodes. Take each one in turn as a traversal root node. foreach (INetworkNode node in networkDef.NodeList) { // Determine if the node has already been visited. if (_visitedNodeSet.Contains(node.Id)) { // Already traversed; Skip. continue; } // Traverse into the node. if (TraverseNode(node.Id)) { // Cycle detected. return(true); } } // No cycles detected. return(false); }
/// <summary> /// Calculate node depths in an acyclic network. /// </summary> public NetworkDepthInfo CalculateNodeDepths(INetworkDefinition networkDef) { // Clear any existing state (allow reuse of this class). _nodeDepthById.Clear(); // Get and store connectivity data for the network. _networkConnectivityData = networkDef.GetConnectivityData(); // Loop over all input (and bias) nodes; Perform a depth first traversal of each in turn. // Set of nodes visited in the current traversal (reset before each individual depth first traversal). HashSet <uint> visitedNodeSet = new HashSet <uint>(); int inputAndBiasCount = networkDef.InputNodeCount + 1; for (int i = 0; i < inputAndBiasCount; i++) { visitedNodeSet.Clear(); TraverseNode(_networkConnectivityData.GetNodeDataByIndex(i), visitedNodeSet, 0); } // Extract node depths from _nodeDepthById into an array of depths (node depth by node index). // Note. Any node not in the dictionary is in an isolated sub-network and will be assigned to // layer 0 by default. INodeList nodeList = networkDef.NodeList; int nodeCount = nodeList.Count; int[] nodeDepthArr = new int[nodeCount]; int maxDepth = 0; // Loop over nodes and set the node depth. Skip over input and bias nodes, they are defined as // being in layer zero. for (int i = inputAndBiasCount; i < nodeCount; i++) { // Lookup the node's depth. If not found depth remains set to zero. int depth; if (_nodeDepthById.TryGetValue(nodeList[i].Id, out depth)) { nodeDepthArr[i] = depth; // Also determine maximum depth, that is, total depth of the network. if (depth > maxDepth) { maxDepth = depth; } } } // Return depth analysis info. return(new NetworkDepthInfo(maxDepth + 1, nodeDepthArr)); }
/// <summary> /// Calculate node depths in an acyclic network. /// </summary> public NetworkDepthInfo CalculateNodeDepths(INetworkDefinition networkDef) { // Clear any existing state (allow reuse of this class). _nodeDepthById.Clear(); // Get and store connectivity data for the network. _networkConnectivityData = networkDef.GetConnectivityData(); // Loop over all input (and bias) nodes; Perform a depth first traversal of each in turn. // Set of nodes visited in the current traversal (reset before each individual depth first traversal). HashSet<uint> visitedNodeSet = new HashSet<uint>(); int inputAndBiasCount = networkDef.InputNodeCount + 1; for(int i=0; i<inputAndBiasCount; i++) { visitedNodeSet.Clear(); TraverseNode(_networkConnectivityData.GetNodeDataByIndex(i), visitedNodeSet, 0); } // Extract node depths from _nodeDepthById into an array of depths (node depth by node index). // Note. Any node not in the dictionary is in an isolated sub-network and will be assigned to // layer 0 by default. INodeList nodeList = networkDef.NodeList; int nodeCount = nodeList.Count; int[] nodeDepthArr = new int[nodeCount]; int maxDepth = 0; // Loop over nodes and set the node depth. Skip over input and bias nodes, they are defined as // being in layer zero. for(int i=inputAndBiasCount; i<nodeCount; i++) { // Lookup the node's depth. If not found depth remains set to zero. int depth; if(_nodeDepthById.TryGetValue(nodeList[i].Id, out depth)) { nodeDepthArr[i] = depth; // Also determine maximum depth, that is, total depth of the network. if(depth > maxDepth) { maxDepth = depth; } } } // Return depth analysis info. return new NetworkDepthInfo(maxDepth+1, nodeDepthArr); }
/// <summary> /// Gets NetworkConnectivityData for the network. /// </summary> public NetworkConnectivityData GetConnectivityData() { if (null != _networkConnectivityData) { return(_networkConnectivityData); } int nodeCount = _nodeList.Count; NodeConnectivityData[] nodeConnectivityDataArr = new NodeConnectivityData[nodeCount]; Dictionary <uint, NodeConnectivityData> nodeConnectivityDataById = new Dictionary <uint, NodeConnectivityData>(nodeCount); // Instantiate NodeConnectivityData for each node. for (int i = 0; i < nodeCount; i++) { uint nodeId = _nodeList[i].Id; NodeConnectivityData ncd = new NodeConnectivityData(nodeId); nodeConnectivityDataArr[i] = ncd; nodeConnectivityDataById.Add(nodeId, ncd); } // Loop connections and register them with the source and target nodes. int conCount = _connectionList.Count; for (int i = 0; i < conCount; i++) { INetworkConnection conn = _connectionList[i]; NodeConnectivityData srcNodeData = nodeConnectivityDataById[conn.SourceNodeId]; NodeConnectivityData tgtNodeData = nodeConnectivityDataById[conn.TargetNodeId]; srcNodeData._tgtNodes.Add(conn.TargetNodeId); tgtNodeData._srcNodes.Add(conn.SourceNodeId); } _networkConnectivityData = new NetworkConnectivityData(nodeConnectivityDataArr, nodeConnectivityDataById); return(_networkConnectivityData); }
/// <summary> /// Gets NetworkConnectivityData for the network. /// </summary> public NetworkConnectivityData GetConnectivityData() { if(null != _networkConnectivityData) { return _networkConnectivityData; } int nodeCount = _nodeList.Count; NodeConnectivityData[] nodeConnectivityDataArr = new NodeConnectivityData[nodeCount]; Dictionary<uint,NodeConnectivityData> nodeConnectivityDataById = new Dictionary<uint,NodeConnectivityData>(nodeCount); // Instantiate NodeConnectivityData for each node. for(int i=0; i<nodeCount; i++) { uint nodeId = _nodeList[i].Id; NodeConnectivityData ncd = new NodeConnectivityData(nodeId); nodeConnectivityDataArr[i] = ncd; nodeConnectivityDataById.Add(nodeId, ncd); } // Loop connections and register them with the source and target nodes. int conCount = _connectionList.Count; for(int i=0; i<conCount; i++) { INetworkConnection conn = _connectionList[i]; NodeConnectivityData srcNodeData = nodeConnectivityDataById[conn.SourceNodeId]; NodeConnectivityData tgtNodeData = nodeConnectivityDataById[conn.TargetNodeId]; srcNodeData._tgtNodes.Add(conn.TargetNodeId); tgtNodeData._srcNodes.Add(conn.SourceNodeId); } _networkConnectivityData = new NetworkConnectivityData(nodeConnectivityDataArr, nodeConnectivityDataById); return _networkConnectivityData; }
/// <summary> /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition. /// </summary> public bool IsNetworkCyclicInternal(INetworkDefinition networkDef) { // Clear any existing state (allow reuse of this class). _ancestorNodeSet.Clear(); _visitedNodeSet.Clear(); // Get and store connectivity data for the network. _networkConnectivityData = networkDef.GetConnectivityData(); // Loop over all nodes. Take each one in turn as a traversal root node. foreach(INetworkNode node in networkDef.NodeList) { // Determine if the node has already been visited. if(_visitedNodeSet.Contains(node.Id)) { // Already traversed; Skip. continue; } // Traverse into the node. if(TraverseNode(node.Id)) { // Cycle detected. return true; } } // No cycles detected. return false; }