/* * Copyright (c) 2005-2006 Erik Tigerholm * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ namespace OpenTraffic.Model.Simulator.Queue { using System; using System.Collections.Generic; using OpenTraffic.Model.Route; class QueueSimulator : ISimulator { private Collections.IPriorityQueue startQueue; private TrafficModel model; private float time; private int iter; private int vehicleEntered; private int simulationIter; // private ILinkSimulator[] links; private List links; private List neighbourHoodLinksIn; private Dictionary neighbourHoodLinksOut; private List vehicles; private List nodes; private RouteAssigner.TrafficRouteAssigner routeAssigner; private RouteGenerator routeGenerator = null; private float ratioChanged; private float ratioStart; public Result.ResultData Result { get { return result; } } public Result.ResultData HistoricalResult { set { historicalResult = value; } } private Result.ResultData historicalResult; private Result.ResultData result; public int PercentFinished { get { if (model == null) return 0; float starttime = model.StartTime; int t = (int)(100 * (time - starttime) / (model.StopTime - starttime)); return Math.Max(0, t); } } public QueueSimulator() { routeGenerator = null; this.ratioChanged = -1; } public QueueSimulator( float ratioChanged, float ratioStart, RouteAssigner.TrafficRouteAssigner ra) { routeGenerator = null; this.ratioChanged = ratioChanged; this.routeAssigner = ra; this.ratioStart = ratioStart; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")] public void Init(TrafficModel m, int id) { this.model = m; vehicles = model.TrafficGenerator.CreateTraffic(model.StopTime); startQueue = new Collections.TrafficHeap(vehicles.Count); iter = 0; // links = new ILinkSimulator[model.Links.Count + model.Connectors.Count]; links = new List(model.TrafficModelLinks.Count + model.TrafficModelConnectors.Count); nodes = new List(model.IntersectionNodes.Count + model.TrafficZones.Count); neighbourHoodLinksIn = new List(); neighbourHoodLinksOut = new Dictionary(); TrafficGenerator.ODTrafficGenerator otg = model.TrafficGenerator as TrafficGenerator.ODTrafficGenerator; if (otg != null) { routeGenerator = new RouteGenerator(otg.Demands, model.Routes, otg.Times); } List linkTemp = new List(); foreach (OpenTraffic.Model.TrafficModelLink l in m.TrafficModelLinks) { initLink(m, id, l, linkTemp); } foreach (OpenTraffic.Model.TrafficModelConnector l in m.TrafficModelConnectors) { initLink(m, id, l, linkTemp); } // links = linkTemp.ToArray(); links.AddRange(linkTemp); foreach (OpenTraffic.Model.IntersectionNode n in m.IntersectionNodes) { if (m.Partition[n.Id] == id) { Node sn = new Node(n, m.Optimize); n.Simulator = sn; nodes.Add(sn); } } foreach (OpenTraffic.Model.IntersectionNode n in m.TrafficZones) { if (m.Partition[n.Id] == id) { Node sn = new Node(n, m.Optimize); n.Simulator = sn; nodes.Add(sn); } } nextStop = model.StartTime; routeAssigner.Clear(); routeAssigner.AddRoute(model.Routes); } private void initLink(TrafficModel m, int id, OpenTraffic.Model.TrafficModelLink l, List links1) { if (m.Partition[l.Target.Id] == id) { ILinkSimulator sl; if (m.Optimize) { sl = new FastLink(l, model.Giveaway, model.AssumeOnlyOneClass, m.Shockwave); } else { sl = new Link(l, model.Giveaway, model.AssumeOnlyOneClass, m.Shockwave); } sl.Clear(); l.Simulator = sl; links1.Add(sl); if (m.Partition[l.Source.Id] != id) { neighbourHoodLinksIn.Add(sl); } } else { if (m.Partition[l.Source.Id] == id) { IVirtualLink sl = null; if (m.Optimize) { sl = new FastVirtualLink(l); } else { sl = new VirtualLink(l); } l.Simulator = sl; neighbourHoodLinksOut.Add(l.Id, sl); } } } public void RestartIteration() { simulationIter = 0; iter++; time = model.StartTime; vehicleEntered = 0; float ratio = 1.0f; if (ratioChanged == -1) { switch ((int)Math.Floor(iter / 10.0f)) { case 0: ratio = 10; break; case 1: ratio = 5; break; default: case 2: ratio = 1; break; } } else { ratio = ratioChanged; } result = model.ResultFactory.CreateResult(); routeAssigner.init(historicalResult, ratio / 100.0f, ratioStart / 100.0f); routeAssigner.AssignRoutes(vehicles); startQueue.Clear(); foreach (Vehicle vehicle in vehicles) { if (vehicle.trafficRoute != null) { startQueue.Add(-vehicle.StartTime, vehicle); } } foreach (ILinkSimulator l in links) { l.Clear(); } nextStop = model.StartTime; } private float nextStop; private float deltaTime = 5.0f; public bool Iterate() { if (model.StartTime == time) { //Console.CursorLeft = 0; //for (int i = 0; i < 50; i++) Console.Write("."); Console.CursorLeft = 0; } if (time >= model.StopTime) { Console.Write(": " + result.VehiclesLeft + "/" + vehicleEntered + "/" + vehicles.Count + " #" + iter ); Console.CursorLeft = 0; result.Close(links); result.CreateRouteResult(vehicles); //xxx return false; } if (time > nextStop) { Console.Write("#"); nextStop += (model.StopTime - model.StartTime) / 49; } // Insert all Vehicles. while (startQueue.Count != 0 && startQueue.Peek().Value.StartTime < time) { vehicleEntered++; Vehicle v = startQueue.Pop().Value; v.trafficRoute.Source.Simulator.Add(v, v.StartTime, 0, result); } if ((vehicleEntered != 0) && (vehicleEntered != result.VehiclesLeft | startQueue.Count != 0)) { if (model.SignalLight) { foreach (SignalPlans.SignalPlan sp in model.SignalPlans) { sp.BlockTurns(time); } } bool even = simulationIter % 2 == 0; for (int i = 0; i < nodes.Count; i++) { nodes[even ? i : nodes.Count - 1 - i].PreSimulate(time - deltaTime, time, result, model); } for (int i = 0; i < nodes.Count; i++) { nodes[!even ? i : nodes.Count - 1 - i].Simulate(time - deltaTime, time, result, model); } if (model.Optimize) { ILinkSimulator[] linksArr = links.ToArray(); for (int i = 0; i < linksArr.Length; i++) { ILinkSimulator l = linksArr[even ? i : linksArr.Length - i - 1]; l.PreSimulate(time - deltaTime, time, result, model); } for (int i = 0; i < linksArr.Length; i++) { ILinkSimulator l = linksArr[even ? i : linksArr.Length - i - 1]; l.Simulate(time - deltaTime, time, result, model); } foreach (KeyValuePair ivl in neighbourHoodLinksOut) { ivl.Value.PreSimulate(time - deltaTime, time, result, model); ivl.Value.Simulate(time - deltaTime, time, result, model); } } } result.Iterate(links, time); time = time + deltaTime; simulationIter++; return true; } public void SyncronizeModel(List vehicles1, List links1) { if (links1 != null) { foreach (LinkInfo li in links1) { neighbourHoodLinksOut[li.Id].Synchronize(li); } if (vehicles1 != null) { foreach (Vehicle v in vehicles1) { vehicleEntered++; v.GetLink().Simulator.Add(v, v.LastTimePassedNode, 0, result); } } } } public bool ShouldSync(Network.ClientDescription cd) { if (cd != null) { foreach (KeyValuePair slKV in neighbourHoodLinksOut) { ILinkSimulator sl = slKV.Value; if (model.Partition[sl.NetworkLink.Target.Id] == cd.id) { return true; } } foreach (ILinkSimulator sl in neighbourHoodLinksIn) { if (model.Partition[sl.NetworkLink.Source.Id] == cd.id) { return true; } } } return false; } public bool GetSyncronizeVehicles(Network.ClientDescription cd, List vehicles1, List links1) { bool should_sync = false; if (cd != null && vehicles1 != null && links1 != null) { foreach (KeyValuePair slKV in neighbourHoodLinksOut) { ILinkSimulator sl = slKV.Value; if (model.Partition[sl.NetworkLink.Target.Id] == cd.id) { sl.AddCarToTransfer(vehicles1); should_sync = true; } } vehicleEntered -= vehicles1.Count; foreach (ILinkSimulator sl in neighbourHoodLinksIn) { if (model.Partition[sl.NetworkLink.Source.Id] == cd.id) { // sl.PreSimulate(time - deltaTime, time, result, model); LinkInfo li = sl.GetLinkInfo(); if (li != null) { links1.Add(li); should_sync = true; } } } } return should_sync; } public List GenerateMoreRoutes() { if (routeGenerator != null) { List routes = routeGenerator.GenerateMoreRoutes(new Route.RouteFactory(model, historicalResult)); routeAssigner.AddRoute(routes); return routes; } return new List(); } } }