コード例 #1
0
        private void _PrintPath(CirclePathTreeNodeModel treeRoot)
        {
            this._logger.LogInformation($"");
            this._logger.LogInformation($"----------START Circle path tree.");
            var pathList = this._GetPathesAsStringList(new List <CirclePathTreeNodeModel>()
            {
                treeRoot
            });

            foreach (var pathItem in pathList)
            {
                this._logger.LogInformation(pathItem);
            }
            this._logger.LogInformation($"----------END Circle path tree.");
            this._logger.LogInformation($"");
        }
コード例 #2
0
        /// <summary>
        /// Traverses the pathes tree and returns a list of pathes.
        /// </summary>
        /// <param name="pathFindResultTreeNode"></param>
        /// <returns></returns>
        private List <List <string> > _BuildPathListFromTree(CirclePathTreeNodeModel pathFindResultTreeNode)
        {
            // recursion safety stop condition 0
            if (pathFindResultTreeNode == null)
            {
                return(null);
            }

            //var result = new List<List<string>>();

            // recursion stop condition 1
            if (pathFindResultTreeNode.IsLeafNode)
            {
                return(new List <List <string> >()
                {
                    new List <string>()
                    {
                        pathFindResultTreeNode.State
                    }
                });
            }
            else
            {
                // recursive call
                var nextResults = pathFindResultTreeNode.NextNodes
                                  .Select(nextNode => this._BuildPathListFromTree(nextNode))
                                  .SelectMany(nextResult => nextResult) // flatten
                                  .Select(nextResult => {
                    // prepend with current state
                    nextResult.Insert(0, pathFindResultTreeNode.State);
                    return(nextResult);
                })
                                  .ToList();

                return(nextResults);
            }
        }
コード例 #3
0
        /// <summary>
        /// Recursive.
        /// <br/>
        /// Finds a set of pathes which describes a valid transition from start state back to itself
        /// according to min/max path length limitations.
        /// <br/>
        /// Result: A tree that represents valid pathes.
        /// </summary>
        /// <param name="absoluteStartState">Static param, doesn't change accross recursive calls.</param>
        /// <param name="relativeStartStates">Dynamic param that changes accross recursive calls.</param>
        /// <param name="pathLength">Dynamic param that changes accross recursive calls.</param>
        /// <returns></returns>
        private List <CirclePathTreeNodeModel> _FindPathTree(string absoluteStartState, List <string> relativeStartStates, int pathLength = -1)
        {
            pathLength += 1;

            List <CirclePathTreeNodeModel> result = relativeStartStates.Select(state =>
            {
                if (pathLength >= 1 && pathLength < this._minPathLenght)
                {
                    if (state == absoluteStartState)
                    {
                        // while we haven't reached the min length forbid absolute start state to apear in path
                        return(null);
                    }
                }
                else if (pathLength >= this._minPathLenght && pathLength < this._maxPathLength)
                {
                    if (state == absoluteStartState)
                    {
                        // min length circle path reached
                        // this._logger.LogInformation($"Found min length circle path: {absoluteStartState} -> {state}. len={pathLength}.");
                        return(new CirclePathTreeNodeModel()
                        {
                            State = state,
                            NextNodes = null,
                            PathLength = pathLength,
                        });
                    }
                }
                else if (pathLength == this._maxPathLength)
                {
                    // max path length reached
                    if (state == absoluteStartState)
                    {
                        // ended in absolute start state - desired result
                        // this._logger.LogInformation($"Max level reached: {absoluteStartState} -> ... -> {state}. len={pathLength}.");
                        return(new CirclePathTreeNodeModel()
                        {
                            State = state,
                            NextNodes = null,
                            PathLength = pathLength,
                        });
                    }
                    else
                    {
                        // ended in other state than start - discard this path
                        return(null);
                    }
                }
                else if (pathLength > this._maxPathLength)
                {
                    // out of path length limits - discard this path
                    return(null);
                }

                var stateTransitions = this._FindStateTransitions(state);
                var nextStates       = this._GetSutableTransitionStatesForState(stateTransitions, state);

                // recursive call
                // traverse down to the tree
                var nextResults = this._FindPathTree(absoluteStartState, nextStates, pathLength);
                if (nextResults != null)
                {
                    var result = new CirclePathTreeNodeModel()
                    {
                        State      = state,
                        NextNodes  = nextResults,
                        PathLength = pathLength,
                    };
                    return(result);
                }

                return(null);
            }).ToList();

            // filter out discarded pathes
            result = result.Where(x => x != null).ToList();
            if (result.Count() == 0)
            {
                return(null);
            }
            return(result);
        }