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;
        }
예제 #5
0
    private void AddListenerToQueue <T, C>(Dictionary <string, PriorityQueue <T> > listeners,
                                           T listener) where T : InputListener <C>
    {
        PriorityQueue <T> queue;

        if (!listeners.TryGetValue(listener.buttonName, out queue))
        {
            queue = new LinkedListPriorityQueue <T>();
            listeners.Add(listener.buttonName, queue);
        }

        queue.Add(listener);
    }
        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);
                }
            }
        }
예제 #7
0
    public static void Main()
    {
        Console.Title = "emergency";
        Intersection[,] intersections = new Intersection[GRID_WIDTH, GRID_HEIGHT];
        futureEvents = new LinkedListPriorityQueue <Event>();
        Event            e;
        SwitchLightEvent sle;
        EndOfRoadEvent   eore;
        bool             hasDriven;

        futureEvents.Add(new ResetStatisticsEvent(0));

        /*initialise intersections*/
        for (int x = 0; x < GRID_WIDTH; x++)
        {
            for (int y = 0; y < GRID_HEIGHT; y++)
            {
                intersections[x, y] = new Intersection();
            }
        }

        /*connect intersections from east to west*/
        for (int x = 0; x < GRID_WIDTH; x++)
        {
            for (int y = 0; y < GRID_HEIGHT; y++)
            {
                Intersection i = intersections[x, y];

                new Road(i, intersections[x, (y + 1) % GRID_HEIGHT], (int)direction.north); //north
                new Road(i, intersections[(x + 1) % GRID_WIDTH, y], (int)direction.east);   //east
                new Road(intersections[x, (y + 1) % GRID_HEIGHT], i, (int)direction.south); //south
                new Road(intersections[(x + 1) % GRID_WIDTH, y], i, (int)direction.west);   //west
            }///end  creating roads
        }
        /*initialise lights*/
        for (int x = 0; x < GRID_WIDTH; x++)
        {
            for (int y = 0; y < GRID_HEIGHT; y++)
            {//initialise lights
                Intersection i = intersections[x, y];

                i.incoming[(int)direction.north].HasGreen = false;
                i.incoming[(int)direction.east].HasGreen  = true;
                i.incoming[(int)direction.south].HasGreen = false;
                i.incoming[(int)direction.west].HasGreen  = true;

                /*initialise light switching*/
                int light = rand.Next(-1 * LIGHT_DURATION, LIGHT_DURATION);
                futureEvents.Add(new SwitchLightEvent(light, i));

                /*place cars on road*/
                for (int j = 0; j < 4; j++)
                {
                    for (int k = 0; k < CARS_PER_ROAD; k++)
                    {
                        futureEvents.Add(new EndOfRoadEvent(0, i.incoming[j], new Vehicle()));
                    }
                }
            }//end of connecting intersection x,y northwards and eastwards
        }
        futureEvents.Add(new GetDestinationEvent(0, new Ambulance()));

        while (time < MAX_TIME && !futureEvents.Empty()) //while there is an event to simulate
        {
            e    = futureEvents.pop();
            time = e.time;

            switch (e.GetType().ToString())
            {
            case "SwitchLightEvent":
                sle = (SwitchLightEvent)e;
                sle.intersection.switchLights();
                sle.intersection.block(YELLOW_LIGHT_DURATION);                                   //simulate the light being yellow, and the brief time that both are red
                futureEvents.Add(new SwitchLightEvent(time + LIGHT_DURATION, sle.intersection)); //create event to switch again
                break;

            case "EndOfRoadEvent":
                eore = (EndOfRoadEvent)e;
                eore.road.waitingVehicles.Add(eore.vehicle);     //place in queue at edge of intersection

                /*check if the vehicle can drive through */
                if (eore.road.to.isClear() && eore.road.HasGreen)
                {
                    eore.road.drive();
                }
                break;

            case "IntersectionClearEvent":
                IntersectionClearEvent ICE = (IntersectionClearEvent)e;
                ICE.intersection.unblock();

                /* if the intersection is now clear, then attempt to drive a car through */
                if (ICE.intersection.isClear())
                {    //cycle through incoming roads, looking for a car to drive
                    hasDriven = false;
                    for (int i = 0; i < 4 && !hasDriven; i++)
                    {
                        if (ICE.intersection.incoming[i].HasGreen && !ICE.intersection.incoming[i].waitingVehicles.Empty())     //if the road is green, and there is a vehicle
                        {
                            ICE.intersection.incoming[i].drive();
                            hasDriven = true;
                        }
                    }

                    if (hasDriven)
                    {
                        ICE.intersection.block(CLEARING_TIME);
                    }
                }    //end if road is clear
                //else there is another blocking event (either a drive or switch light)
                break;

            case "ResetStatisticsEvent":     //reset statistics to clear away any fluff caused by initialisation
                Road.numTrafficJams = Road.numSwitches = Ambulance.totalTime = Ambulance.numTrips = 0;
                break;

            case "GetDestinationEvent":     //sets a path for an ambulance to follow, then drives it
                GetDestinationEvent gde = (GetDestinationEvent)e;

                gde.ambulance.createPath(2);
                gde.ambulance.startTime = time;

                Road startingRoad = intersections[0, 0].outgoing[(int)direction.north];  //hardcode starting road

                futureEvents.Add(new EndOfRoadEvent(time, startingRoad, gde.ambulance)); //put it on the road

                if (Ambulance.numTrips >= MAX_TRIPS)                                     //if enough trips have been taken
                {
                    futureEvents.MakeEmpty();                                            //trick the event loop to end
                }
                break;

            default:
                throw new System.NotImplementedException("no implementation for event " + e.GetType());
            } //end switch
        }     //end while there is a future event

        Console.WriteLine("There were {0} jams out of a total of {1} switches, for a rate of {2}%", Road.numTrafficJams, Road.numSwitches, (double)Road.numTrafficJams / Road.numSwitches);
        Console.WriteLine("The ambulance took {0} trips, with an average time of {1}", Ambulance.numTrips, (double)Ambulance.totalTime / Ambulance.numTrips);
        Console.WriteLine("done");
        //printGrid(intersections);
        Console.Read();
    }//end of Main
예제 #8
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);
            }
        }