Stored the IDs of nodes that connect in and out of a given node.
        private void TraverseNode(NodeConnectivityData nodeData, HashSet <uint> visitedNodeSet, int depth)
        {
            // Check if the node has already been encountered during the current traversal (have we followed a cycle in the connectivity).
            if (visitedNodeSet.Contains(nodeData._id))
            {   // Dont follow cycles.
                return;
            }

            // Register the visit.
            visitedNodeSet.Add(nodeData._id);

            // Check if the node has been traversed by a previous traversal.
            int assignedDepth;

            if (_nodeDepthById.TryGetValue(nodeData._id, out assignedDepth) && assignedDepth >= depth)
            {   // The node already has already been visited via a path that assigned it a greater depth than the
                // current path. Stop traversing this path.
                return;
            }

            // Either this is the first visit to the node *or* the node has been visited, but via a shorter path.
            // Either way we assign it the current depth value and traverse into its targets to update/set their depth.
            _nodeDepthById[nodeData._id] = depth;
            foreach (uint targetId in nodeData._tgtNodes)
            {
                TraverseNode(_networkConnectivityData.GetNodeDataById(targetId), visitedNodeSet, depth + 1);
            }
        }
        private void TraverseNode(NodeConnectivityData nodeData, int depth)
        {
            // Check if the node has been visited before.
            int assignedDepth;
            if(_nodeDepthById.TryGetValue(nodeData._id, out assignedDepth) && assignedDepth >= depth)
            {   // The node already has already been visited via a path that assigned it a greater depth than the 
                // current path. Stop traversing this path.
                return;
            }

            // Either this is the first visit to the node *or* the node has been visited, but via a shorter path.
            // Either way we assign it the current depth value and traverse into its targets to update/set their depth.
            _nodeDepthById[nodeData._id] = depth;
            foreach(uint targetId in nodeData._tgtNodes)
            {
                TraverseNode(_networkConnectivityData.GetNodeDataById(targetId), depth + 1);
            }
        }
예제 #3
0
        private bool TraverseNode(uint nodeId)
        {
            // Is the node on the current stack of traversal ancestor nodes?
            if (_ancestorNodeSet.Contains(nodeId))
            {   // Connectivity cycle detected.
                return(true);
            }

            // Have we already traversed this node?
            if (_visitedNodeSet.Contains(nodeId))
            {   // Already visited; Skip.
                return(false);
            }

            // Traverse into the node's targets / children (if it has any)
            NodeConnectivityData node = _networkConnectivityData.GetNodeDataById(nodeId);

            if (0 == node._tgtNodes.Count)
            {   // No cycles on this traversal path.
                return(false);
            }

            // Register node with set of traversal path ancestor nodes.
            _ancestorNodeSet.Add(nodeId);

            // Register the node as having been visited.
            _visitedNodeSet.Add(nodeId);

            // Traverse into targets.
            foreach (uint targetId in node._tgtNodes)
            {
                if (TraverseNode(targetId))
                {   // Cycle detected.
                    return(true);
                }
            }

            // Remove node from set of traversal path ancestor nodes.
            _ancestorNodeSet.Remove(nodeId);

            // No cycles were detected in the traversal paths from this node.
            return(false);
        }
예제 #4
0
        private void TraverseNode(NodeConnectivityData nodeData, int depth)
        {
            // Check if the node has been visited before.
            int assignedDepth;

            if (_nodeDepthById.TryGetValue(nodeData._id, out assignedDepth) && assignedDepth >= depth)
            {   // The node already has already been visited via a path that assigned it a greater depth than the
                // current path. Stop traversing this path.
                return;
            }

            // Either this is the first visit to the node *or* the node has been visited, but via a shorter path.
            // Either way we assign it the current depth value and traverse into its targets to update/set their depth.
            _nodeDepthById[nodeData._id] = depth;
            foreach (uint targetId in nodeData._tgtNodes)
            {
                TraverseNode(_networkConnectivityData.GetNodeDataById(targetId), depth + 1);
            }
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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;
        }
        private void TraverseNode(NodeConnectivityData nodeData, HashSet<uint> visitedNodeSet, int depth)
        {
            // Check if the node has already been encountered during the current traversal (have we followed a cycle in the connectivity).
            if(visitedNodeSet.Contains(nodeData._id)) 
            {   // Dont follow cycles.
                return;
            }

            // Register the visit.
            visitedNodeSet.Add(nodeData._id);

            // Check if the node has been traversed by a previous traversal.
            int assignedDepth;
            if(_nodeDepthById.TryGetValue(nodeData._id, out assignedDepth) && assignedDepth >= depth)
            {   // The node already has already been visited via a path that assigned it a greater depth than the 
                // current path. Stop traversing this path.
                return;
            }

            // Either this is the first visit to the node *or* the node has been visited, but via a shorter path.
            // Either way we assign it the current depth value and traverse into its targets to update/set their depth.
            _nodeDepthById[nodeData._id] = depth;
            foreach(uint targetId in nodeData._tgtNodes)
            {
                TraverseNode(_networkConnectivityData.GetNodeDataById(targetId), visitedNodeSet, depth + 1);
            }
        }
예제 #8
0
 /// <summary>
 /// Construct with the provided connectivity data.
 /// </summary>
 public NetworkConnectivityData(NodeConnectivityData[] nodeConnectivityDataArr,
                                Dictionary<uint,NodeConnectivityData> nodeConnectivityDataById)
 {
     _nodeConnectivityDataArr = nodeConnectivityDataArr;
     _nodeConnectivityDataById = nodeConnectivityDataById;
 }