public StationEntity this[string stationName, string lineName] { get { if (stationList == null) { stationList = new List <StationEntity>(); } StationEntity matchedStation = SearchStationFromStationList(stationName, lineName); if (needCheckQuery) { if (matchedStation == null) { try { matchedStation = SeachStationByQuery(stationName, lineName); stationList.Add(matchedStation); } catch (Exception exception) { throw exception; } } } return(matchedStation); } }
internal bool QuickGetRoute(StationEntity fromStation, List <StationLineEntityExtender> stationLineListCache) { List <Tuple <StationLineEntityExtender, int> > routeTree = new List <Tuple <StationLineEntityExtender, int> >(); routeTree.Add(new Tuple <StationLineEntityExtender, int>(this, -1)); bool found = GenerateRouteTree(fromStation, stationLineListCache, routeTree); if (!found) { return(false); } List <StationLineEntityExtender> route = GenerateRoute(routeTree); // calculate the time int index = 0; TimeSpan totalCost = new TimeSpan(route[0].TimeWait.Ticks / 2); while (index + 1 < route.Count) { TimeSpan cost = CalculateTimeCost(route[index], route[index + 1], stationLineListCache); totalCost += cost; index++; } this.MinimumTime = totalCost; return(true); }
internal static List <StationLineEntityExtender> Convert(StationEntity station, List <StationLineEntityExtender> stationLineListCache) { List <StationLineEntity> stationLineList = station.StationLineList; List <StationLineEntityExtender> stationLineExtenderList = new List <StationLineEntityExtender>(); foreach (StationLineEntity stationLine in stationLineList) { stationLineExtenderList.Add(Convert(stationLine, stationLineListCache)); } return(stationLineExtenderList); }
private StationEntity SeachStationByQuery(string stationName, string lineName) { // get all matched stations List <StationEntity> matchedStationList = metroWeb.StationList[stationName]; if (matchedStationList.Count == 0) { throw new Exception(string.Format("The station {0} is not found.", stationName)); } // get all matched lines List <LineEntity> matchedlineList = metroWeb.LineList[lineName]; if (matchedlineList.Count == 0) { throw new Exception(string.Format("The line {0} is not found.", lineName)); } // combine them List <StationLineEntity> stationLines = new List <StationLineEntity>(); foreach (StationEntity station in matchedStationList) { foreach (LineEntity line in matchedlineList) { try { stationLines.Add(metroWeb.StationLineList[station.StationId, line.LineId]); break; } catch { } } } if (stationLines.Count == 0) { throw new Exception(string.Format("The station {0} in line {1} is not found.", stationName, lineName)); } int searchedStationId = stationLines[0].Station.StationId; if (stationLines.Any(stationLine => stationLine.Station.StationId != searchedStationId)) { throw new Exception(string.Format("The station {0} in line {1} is ambiguous. Please choose other way to identify.", stationName, lineName)); } // find it StationEntity searchedStation = matchedStationList.Find(station => station.StationId == searchedStationId); return(searchedStation); }
private StationEntity SeachStationByQuery(int stationId) { List <Station> matchedStationList = metroWeb.MetroWebDatabase.Table <Station>().Select(new Station { StationId = stationId }); if (matchedStationList.Count == 0) { throw new Exception(string.Format("The station id {0} is not found.", stationId)); } StationEntity matchedStationEntity = new StationEntity(metroWeb, matchedStationList[0]); return(matchedStationEntity); }
private List <StationEntity> SeachStationByQuery() { List <Station> matchedStationList = metroWeb.MetroWebDatabase.Table <Station>().Select(); List <StationEntity> matchedStationEntityList = new List <StationEntity>(); foreach (Station matchedStation in matchedStationList) { if (!stationList.Exists(station => station.StationId == matchedStation.StationId)) { StationEntity stationEntity = new StationEntity(metroWeb, matchedStation); matchedStationEntityList.Add(stationEntity); } } return(matchedStationEntityList); }
private bool GenerateRouteTree(StationEntity fromStation, List <StationLineEntityExtender> stationLineListCache, List <Tuple <StationLineEntityExtender, int> > routeTree) { int index = 0; while (index < routeTree.Count) { StationLineEntityExtender currentStationLineExtender = routeTree[index].Item1; List <StationLineEntity> currentStationLinePreviousStationLineList = currentStationLineExtender.PreviousStationLineList; StationLineEntity fromStationLine = currentStationLinePreviousStationLineList.Find( currentStationLinePreviousStationLine => currentStationLinePreviousStationLine.Station == fromStation); if (fromStationLine != null) { // found StationLineEntityExtender fromStationLineExtender = Convert(fromStationLine, stationLineListCache); routeTree.Add(new Tuple <StationLineEntityExtender, int>(fromStationLineExtender, index)); return(true); } else { // not found foreach (StationLineEntity currentStationLinePreviousStationLine in currentStationLinePreviousStationLineList) { if (currentStationLinePreviousStationLine.Station.StationId == 101) { } List <MetroTransferEntity> transferFromList = currentStationLinePreviousStationLine.TransferFromList; foreach (MetroTransferEntity transferFrom in transferFromList) { StationLineEntity transferFromStationLine = transferFrom.FromStationLine; StationLineEntityExtender transferFromStationLineExtender = Convert(transferFromStationLine, stationLineListCache); if (!routeTree.Exists(stationLine => stationLine.Item1 == transferFromStationLineExtender)) { routeTree.Add(new Tuple <StationLineEntityExtender, int>(transferFromStationLineExtender, index)); } } } } index++; } return(false); }
internal bool FullyGetRoute(StationEntity fromStation, List <StationLineEntityExtender> stationLineListCache, TimeSpan arrivedTimeLimit, Stack <StationLineEntityExtender> stationLineExtenderStatck) { // if current StationLine is the from staiton, return true if (this.Station == fromStation) { MinimumTime = new TimeSpan(TimeWait.Ticks / 2); MinimumRoute.Clear(); MinimumRoute.Add(this); return(true); } // if current stationline is the end station, return false StationLineEntityExtender previousStationLineExtender = null; if (this.PreviousStationLine != null) { previousStationLineExtender = Convert(this.PreviousStationLine, stationLineListCache); if (stationLineExtenderStatck.Contains(previousStationLineExtender)) // avoid death loop { previousStationLineExtender = null; } } List <StationLineEntityExtender> transferStationLineExtenderList = this.TransferFromList.Select( metroTransfer => Convert(metroTransfer.FromStationLine, stationLineListCache)).ToList(); // todo: this may return duplicate stationlines for (int i = transferStationLineExtenderList.Count - 1; i >= 0; i--) // avoid death loop { if (stationLineExtenderStatck.Contains(transferStationLineExtenderList[i])) { transferStationLineExtenderList.RemoveAt(i); } } if (previousStationLineExtender == null && transferStationLineExtenderList.Count == 0) { return(false); } // if the previouStationLine is not the 'from' station, and the minmimum arrived time is greater than newArrivedTimeLimit, so we don't need to go further bool finalResult = false; if (previousStationLineExtender != null) { TimeSpan newArrivedTimeLimit = arrivedTimeLimit - this.TimeArrived; TimeSpan previousStationLineArrivedMin = previousStationLineExtender.TimeArrived; foreach (MetroTransferEntity metroTransfer in previousStationLineExtender.TransferFromList) { if (Convert(metroTransfer.ToStationLine, stationLineListCache) == previousStationLineExtender) { TimeSpan transferCost = metroTransfer.TimeTransfer + new TimeSpan(previousStationLineExtender.TimeWait.Ticks / 2); previousStationLineArrivedMin = previousStationLineArrivedMin > transferCost ? transferCost : previousStationLineArrivedMin; } } if (previousStationLineExtender.Station == fromStation || previousStationLineArrivedMin <= newArrivedTimeLimit) { // get previous station FullyGetRoute stationLineExtenderStatck.Push(this); previousStationLineExtender.TransferTimes = this.TransferTimes; bool found = previousStationLineExtender.FullyGetRoute(fromStation, stationLineListCache, newArrivedTimeLimit, stationLineExtenderStatck); stationLineExtenderStatck.Pop(); if (found) { // compare whether current route is the minimum route TimeSpan arriveTimeCost = previousStationLineExtender.MinimumTime + TimeArrived; if (arriveTimeCost < MinimumTime) { MinimumTime = arriveTimeCost; MinimumRoute = new List <StationLineEntity>(previousStationLineExtender.MinimumRoute); MinimumRoute.Add(this); } finalResult = true; } } } // if we have already been transfered 4 times, we don't need to transfer any more because it is definitly not the nearest route if (TransferTimes < 5) { // if the transferStation is not the 'from' station, and the minmimum arrived time is greater than newArrivedTimeLimit, so we don't need to go further foreach (StationLineEntityExtender transferStationLine in transferStationLineExtenderList) { List <MetroTransferEntity> toMetroTransferList = transferStationLine.TransferToList; MetroTransferEntity metroTransfer = toMetroTransferList.Find(mt => Convert(mt.ToStationLine, stationLineListCache) == this); if (metroTransfer == null) { throw new Exception("Cannot find the transfer data, something wrong?!"); } TimeSpan transferTimeCost = metroTransfer.TimeTransfer + new TimeSpan(this.TimeWait.Ticks / 2); TimeSpan newArrivedTimeLimit = arrivedTimeLimit - transferTimeCost - transferStationLine.TimeArrived; StationLineEntityExtender transferStationPreviousStationLine = Convert(transferStationLine.PreviousStationLine, stationLineListCache); TimeSpan transferStationLineArrivedMin = transferStationPreviousStationLine.TimeArrived; foreach (MetroTransferEntity transferMetroTransfer in transferStationPreviousStationLine.TransferFromList) { if (Convert(metroTransfer.ToStationLine, stationLineListCache) == transferStationLine) { TimeSpan transferCost = transferMetroTransfer.TimeTransfer + new TimeSpan(transferStationLine.TimeWait.Ticks / 2); transferStationLineArrivedMin = transferStationLineArrivedMin > transferCost ? transferCost : transferStationLineArrivedMin; } } if (transferStationPreviousStationLine.Station == fromStation || transferStationLineArrivedMin <= newArrivedTimeLimit) { // get transfer station stationLineExtenderStatck.Push(this); transferStationPreviousStationLine.TransferTimes = this.TransferTimes + 1; bool found = transferStationPreviousStationLine.FullyGetRoute(fromStation, stationLineListCache, newArrivedTimeLimit, stationLineExtenderStatck); stationLineExtenderStatck.Pop(); if (found) { // compare whether current route is the minimum route TimeSpan arriveTimeCost = transferStationPreviousStationLine.MinimumTime + TimeArrived + transferTimeCost; if (arriveTimeCost < MinimumTime) { MinimumTime = arriveTimeCost; MinimumRoute = new List <StationLineEntity>(transferStationPreviousStationLine.MinimumRoute); MinimumRoute.Add(transferStationLine); } finalResult = true; } } } } return(finalResult); }