public override void Initialize()
        {
            base.Initialize();

            OnFinalSearchSpaceCreated();

            var totalCount = SearchSpace.Count + TargetNodes.Count;

            // Sort edges if PreFilledSpanThreshold is satisfied.
            if (TargetNodes.Count / (double)totalCount >= PreFilledSpanThreshold)
            {
                using (var prioQueue = new LinkedListPriorityQueue <DirectedGraphEdge>(100, totalCount * totalCount))
                {
                    // A PriorityQueue is used for sorting. Should be faster than sorting-methods that don't exploit
                    // sorting ints.
                    var enqueued = 0;
                    for (var i = 0; i < totalCount; i++)
                    {
                        for (var j = i + 1; j < totalCount; j++)
                        {
                            prioQueue.Enqueue(new DirectedGraphEdge(i, j), Distances[i, j]);
                            enqueued++;
                        }
                    }

                    _orderedEdges = new List <DirectedGraphEdge>(enqueued);
                    while (!prioQueue.IsEmpty)
                    {
                        _orderedEdges.Add(prioQueue.Dequeue());
                    }
                }
            }

            InitializeGa();
        }
예제 #2
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;
        }
예제 #3
0
        public void TestPriorityQueue()
        {
            int[] queueTestOrder = { 10, 3, 11, 6, -3, 17, 13, -6, 2, 8, -2, -8 };
            int   nodeCount      = 0;

            for (int i = 0; i < queueTestOrder.Length; i++)
            {
                nodeCount = Math.Max(queueTestOrder[i] + 1, nodeCount);
            }

            LinkedListPriorityQueue <TestNode> queue = new LinkedListPriorityQueue <TestNode>(30);


            TestNode[] testNodes = new TestNode[nodeCount];
            for (int i = 0; i < nodeCount; i++)
            {
                testNodes[i] = new TestNode();
            }

            for (int i = 0; i < queueTestOrder.Length; i++)
            {
                int t = queueTestOrder[i];

                if (t > 0)
                {
                    queue.Enqueue(testNodes[t], t);
                }
                if (t < 0)
                {
                    Assert.IsTrue(queue.Dequeue().Priority == -t);
                }
            }
        }
예제 #4
0
        /// <summary>
        ///     Uses Prim's algorithm to build an MST spanning the mstNodes.
        ///     O(|mstNodes|^2) runtime.
        /// </summary>
        /// <param name="startIndex">The node index to start from.</param>
        /// <param name="edges">Cache for the edges used.</param>
        public void Span(int startIndex, ITwoDArray<DirectedGraphEdge> edges)
        {
            // All nodes that are not yet included.
            var toAdd = new List<int>(_mstNodes.Count);
            // If the index node is already included.
            var inMst = new bool[_distances.CacheSize];
            // The spanning edges.
            var mstEdges = new List<DirectedGraphEdge>(_mstNodes.Count);

            using (var adjacentEdgeQueue = new LinkedListPriorityQueue<DirectedGraphEdge>(100, _mstNodes.Count*_mstNodes.Count))
            {
                foreach (var t in _mstNodes)
                {
                    if (t != startIndex)
                    {
                        toAdd.Add(t);
                        adjacentEdgeQueue.Enqueue(edges[startIndex, t]);
                    }
                }
                inMst[startIndex] = true;

                while (toAdd.Count > 0 && !adjacentEdgeQueue.IsEmpty)
                {
                    int newIn;
                    DirectedGraphEdge shortestEdge;
                    // Dequeue and ignore edges that are already inside the MST.
                    // Add the first one that is not.
                    do
                    {
                        shortestEdge = adjacentEdgeQueue.Dequeue();
                        newIn = shortestEdge.Outside;
                    } while (inMst[newIn]);
                    mstEdges.Add(shortestEdge);
                    inMst[newIn] = true;

                    // Find all newly adjacent edges and enqueue them.
                    for (var i = 0; i < toAdd.Count; i++)
                    {
                        var otherNode = toAdd[i];
                        if (otherNode == newIn)
                        {
                            toAdd.RemoveAt(i--);
                        }
                        else
                        {
                            adjacentEdgeQueue.Enqueue(edges[newIn, otherNode]);
                        }
                    }
                }
            }

            SpanningEdges = mstEdges;
        }
        public void Test()
        {
            int[] queueTestOrder = { 10, 3, 11, 6, -3, 17, 13, -6, 2, 8, -2, -8 };

            var queue = new LinkedListPriorityQueue <TestNode>(30, queueTestOrder.Length);

            foreach (int t in queueTestOrder)
            {
                if (t > 0)
                {
                    queue.Enqueue(new TestNode(t), (uint)t);
                }
                if (t < 0)
                {
                    Assert.IsTrue(queue.Dequeue().Priority == -t);
                }
            }
        }
예제 #6
0
        public void TestPriorityQueue()
        {

            int[] queueTestOrder = { 10, 3, 11, 6, -3, 17, 13, -6, 2, 8, -2, -8 };

            LinkedListPriorityQueue<TestNode> queue = new LinkedListPriorityQueue<TestNode>(30, queueTestOrder.Length);

            foreach (int t in queueTestOrder)
            {
                if (t > 0)
                    queue.Enqueue(new TestNode((uint)t));
                if (t < 0)
                    Assert.IsTrue(queue.Dequeue().Priority == -t);
            }
        }