예제 #1
0
        /// <summary>
        ///  Initializes the solver so that the optimization can be run.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// If not all target nodes are connected to the start node.
        /// </exception>
        public void Initialize()
        {
            BuildSearchGraph();

            _searchSpace =
                _searchGraph.NodeDict.Values.Where(n => IncludeNode(n) && n != StartNodes && !TargetNodes.Contains(n))
                .ToList();

            var consideredNodes = SearchSpace.Concat(TargetNodes).ToList();

            consideredNodes.Add(StartNodes);
            Distances.CalculateFully(consideredNodes);

            if (_targetNodes.Any(node => !Distances.AreConnected(StartNodes, node)))
            {
                throw new InvalidOperationException("The graph is disconnected.");
            }

            // Saving the leastSolution as initial solution. Makes sure there is always a
            // solution even if the search space is empty or MaxGeneration is 0.
            BestSolution = SpannedMstToSkillnodes(CreateLeastSolution());

            var removedNodes   = new List <GraphNode>();
            var newSearchSpace = new List <GraphNode>();

            foreach (var node in SearchSpace)
            {
                if (IncludeNodeUsingDistances(node))
                {
                    newSearchSpace.Add(node);
                }
                else
                {
                    removedNodes.Add(node);
                }
            }
            _searchSpace = newSearchSpace;

            var remainingNodes = SearchSpace.Concat(TargetNodes).ToList();

            remainingNodes.Add(StartNodes);
            Distances.RemoveNodes(removedNodes, remainingNodes);

            if (_targetNodes.Count / (double)remainingNodes.Count >= PreFilledSpanThreshold)
            {
                var prioQueue = new LinkedListPriorityQueue <LinkedGraphEdge>(100);
                for (var i = 0; i < remainingNodes.Count; i++)
                {
                    for (var j = i + 1; j < remainingNodes.Count; j++)
                    {
                        prioQueue.Enqueue(new LinkedGraphEdge(i, j), Distances[i, j]);
                    }
                }
                _firstEdge = prioQueue.First;
            }

            InitializeGa();

            _isInitialized = true;
        }