internal int CountConnection(string c, string d) { Station a = Stations.Find(x => x.Name == c); Station b = Stations.Find(x => x.Name == d); return(Connections.FindAll(x => x.BeginStation == a && x.EndStation == b).Count); }
public void AddConnection(string begin, string end, string lineName, int type) { if (HasStation(begin) && HasStation(end)) { if (!HasConnection(begin, end, lineName)) { Station beginStation = Stations.Find(x => x.Name == begin); Station endStation = Stations.Find(x => x.Name == end); Connection connection = new Connection(beginStation, endStation, lineName, type); Connections.Add(connection); if (map.Contains(beginStation)) { List <Connection> cons = (List <Connection>)map[beginStation]; cons.Add(connection); } else { List <Connection> cons = new List <Connection>(); cons.Add(connection); map.Add(beginStation, cons); } } } else { throw new System.ArgumentException("Invalid Connection!"); } }
public void SetEndStation(string name) { this.EndStation = Stations.Find(x => x.Name == name); }
public Station GetStation(string stationName) { return(Stations.Find(x => x.Name == stationName)); }
public List <Connection> GetDirections(string mode) { int transferCost = mode == "-b" ? 0 : mode == "-c" ? 10000 : -1; if (transferCost < 0) { throw new AggregateException("模式错误"); } if (this.StartStation == null || this.EndStation == null) { throw new Exception("站点未设置!"); } if (this.StartStation.Equals(this.EndStation)) { return(new List <Connection>()); } Queue <Station> queue = new Queue <Station>(); Hashtable routeMap = new Hashtable(); List <List <Connection> > initRouteList = new List <List <Connection> >(); List <Connection> initRoute = new List <Connection>(); Connection initConnection = new Connection(Stations.Find(x => x.Id == 0), Stations.Find(x => x.Id == 0), "*", -1); initRoute.Add(initConnection); initRouteList.Add(initRoute); routeMap.Add(this.StartStation, initRouteList); queue.Enqueue(this.StartStation); List <List <Connection> > tRouteList = null; List <Connection> tRoute = null; while (queue.Count != 0) { Station now = queue.Dequeue(); List <List <Connection> > routeList = (List <List <Connection> >)routeMap[now]; ((List <Connection>)map[now]).ForEach(line => { routeList.ForEach(route => { if (!routeMap.Contains(line.EndStation)) { routeMap.Add(line.EndStation, new List <List <Connection> >()); } tRouteList = (List <List <Connection> >)routeMap[line.EndStation]; int alreadyCost = CountCost(mode, tRouteList.Find(x => true)); int nowCost = CountCost(mode, route) + (mode == "-b" ? 1 : mode == "-c" && route.Count != 1 && route.FindLast(x => true).LineName != line.LineName ? 1 : 0); if (nowCost < alreadyCost) { tRouteList = new List <List <Connection> >(); tRoute = new List <Connection>(route); tRoute.Add(line); tRouteList.Add(tRoute); routeMap[line.EndStation] = tRouteList; if (!queue.Contains(line.EndStation)) { queue.Enqueue(line.EndStation); } } else if (nowCost == alreadyCost) { tRoute = new List <Connection>(route); tRoute.Add(line); if (CanBetter(tRouteList, tRoute, mode)) { tRouteList.Add(tRoute); if (!queue.Contains(line.EndStation)) { queue.Enqueue(line.EndStation); } } } }); }); } if (!routeMap.Contains(this.EndStation)) { throw new ArgumentException("站点不连通"); } tRouteList = (List <List <Connection> >)routeMap[this.EndStation]; tRoute = tRouteList[0]; tRouteList.ForEach(x => { if (tRoute.Count > x.Count) { tRoute = x; } else if (tRoute.Count == x.Count) { tRoute = CountCost("-c", tRoute) > CountCost("-c", x) ? x : tRoute; } }); tRoute.RemoveAt(0); return(tRoute); }
public void Simulate() { TimeSpan earliestStartTime = travelPlanDatas.Min(d => d.StartTime); Clock.Time = earliestStartTime.Subtract(TimeSpan.FromMinutes(10)); Console.WriteLine($"Clock set to: {earliestStartTime}."); Clock.IsPrintingTime = true; int maxEventAmount = travelPlanDatas.Count * 2; int eventCounter = 0; List <StationConnection> trackSections = TrackDescription.StationConnections; while (true) { TimeSpan clockTime = Clock.Time; string timeString = clockTime.ToString(@"hh\:mm", CultureInfo.InvariantCulture); for (int i = 0; i < travelPlanDatas.Count; i++) { TravelPlanData data = travelPlanDatas[i]; // ----Level crossing ---- StationConnection connectionWithCrossing = trackSections.FirstOrDefault(s => s.StartStationID == travelPlanDatas[i].StartStationID && s.ArriveStationID == travelPlanDatas[i].ArriveStationID && s.TrackParts.Contains('=')); hasLevelCrossing = connectionWithCrossing != null; if (hasLevelCrossing) { // level crossing is located between two stations levelCrossing = connectionWithCrossing.Distance * 10 / 2.0; maxSpeed = Trains.Find(train => train.ID == data.TrainID).MaxSpeed; currentPosition = 1.0 * (clockTime.Subtract(data.StartTime)).TotalHours * maxSpeed; if (!TrainsNearLevelCrossing.Contains(data.TrainID) && currentPosition >= levelCrossing - border && currentPosition <= levelCrossing + border) { TrainsNearLevelCrossing.Add(data.TrainID); // Add a train to the TrainsNearLevelCrossing list when the train approches level crossing } } // check if data HasStarted if (!data.HasStarted && data.StartTime <= clockTime) { string trainName = Trains.Find(train => train.ID == data.TrainID).Name; string stationName = Stations.Find(station => station.ID == data.StartStationID).StationName; travelPlanDatas[i].HasStarted = true; TimeSpan travelTime = CalculateTravelTime(data); int timeDeviationInMinutes = GetTimeDeviationInMinutes(data.StartTime, data.ArriveTime, travelTime); travelPlanDatas[i].TimeDeviationInMinutes = timeDeviationInMinutes; travelPlanDatas[i].ArriveTime = data.StartTime.Add(travelTime); eventCounter++; string output = $"[{timeString}]: {trainName} is departing from {stationName}."; Console.WriteLine(output); } else if (hasLevelCrossing && currentPosition >= levelCrossing - border && currentPosition <= levelCrossing + border && isOpen) { CloseLevelCrossing(timeString); // close level crossing when the train is near } else if (hasLevelCrossing && currentPosition > levelCrossing + border && TrainsNearLevelCrossing.Contains(data.TrainID)) { TrainsNearLevelCrossing.Remove(data.TrainID); // when the train leaves zone near level crossing remove it from TrainsNearLevelCrossing list if (!isOpen && TrainsNearLevelCrossing.Count() == 0) // open level crossing if there are no other trains near { OpenLevelCrossing(timeString); } } // check if data HasArrived else if (!data.HasArrived && data.ArriveTime <= clockTime) { string trainName = Trains.Find(train => train.ID == data.TrainID).Name; string stationName = Stations.Find(station => station.ID == data.ArriveStationID).StationName; travelPlanDatas[i].HasArrived = true; eventCounter++; string output = $"[{timeString}]: {trainName} is arriving at {stationName}."; if (data.TimeDeviationInMinutes > 0) { output += $" The train was delayed by {data.TimeDeviationInMinutes} minutes."; } else if (data.TimeDeviationInMinutes < 0) { output += $" The train is early by {Math.Abs(data.TimeDeviationInMinutes)} minutes."; } Console.WriteLine(output); } } if (eventCounter == maxEventAmount) { break; } Thread.Sleep(10); } }