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(); }
/// <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; }
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); } } }
/// <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; }
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); } } }
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
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); } }