Пример #1
0
def markOvertaken(options, vehicleStopRoutes, stopRoutes):
    # mark stops that should not participate in constraint generation
    # once a vehice appears to be "overtaken" (based on inconsistent
    # arrival/until timing), all subsequent stops of that vehicle should no
    # longer be used for contraint generation
    for vehicle, stopRoute in vehicleStopRoutes.items():
        overtaken = False
        for i, (edgesBefore, stop) in enumerate(stopRoute):
            if not (stop.hasAttribute("arrival") and stop.hasAttribute("until")):
                continue
            if options.skipParking and parseBool(stop.getAttributeSecure("parking", "false")):
                continue
            if not overtaken:
                arrival = parseTime(stop.arrival)
                until = parseTime(stop.until)
                for edgesBefore2, stop2 in stopRoutes[stop.busStop]:
                    if stop2.vehID == stop.vehID:
                        continue
                    if not stop2.hasAttribute("arrival") or not stop2.hasAttribute("until"):
                        continue
                    if options.skipParking and parseBool(stop2.getAttributeSecure("parking", "false")):
                        continue
                    arrival2 = parseTime(stop2.arrival)
                    until2 = parseTime(stop2.until)
                    if arrival2 > arrival and until2 < until:
                        overtaken = True
                        print(("Vehicle %s (%s, %s) overtaken by %s (%s, %s) " +
                               "at stop %s (index %s) and ignored afterwards") %
                              (stop.vehID, humanReadableTime(arrival), humanReadableTime(until),
                               stop2.vehID, humanReadableTime(arrival2), humanReadableTime(until2),
                               stop.busStop, i),
                              file=sys.stderr)
                        break
            if overtaken:
                stop.setAttribute("invalid", True)
Пример #2
0
def computeSignalTimes(options, net, stopRoutes):
    signalTimes = defaultdict(list)  # signal -> [(timeAtSignal, stop), ...]
    debugInfo = []
    for busStop, stops in stopRoutes.items():
        for edgesBefore, stop in stops:
            if stop.hasAttribute("arrival"):
                arrival = parseTime(stop.arrival)
            elif stop.hasAttribute("until"):
                arrival = parseTime(stop.until) - parseTime(
                    stop.getAttributeSecure("duration", "0"))
            else:
                continue
            for i, edge in enumerate(edgesBefore):
                node = net.getEdge(edge).getFromNode()
                if node.getType() == "rail_signal":
                    tls = net.getTLS(node.getID())
                    for inLane, outLane, linkNo in tls.getConnections():
                        if outLane.getEdge().getID() == edge:
                            signal = tls.getID()
                            ttSignalStop = getTravelTime(net, edgesBefore[i:])
                            timeAtSignal = arrival - ttSignalStop
                            signalTimes[signal].append((timeAtSignal, stop))
                            if signal == options.debugSignal:
                                debugInfo.append((
                                    timeAtSignal,
                                    "%s vehID=%s prevTripId=%s passes signal %s to stop %s arrival=%s ttSignalStop=%s edges=%s"
                                    %
                                    (humanReadableTime(timeAtSignal),
                                     stop.vehID, stop.prevTripId, signal,
                                     stop.busStop, humanReadableTime(arrival),
                                     ttSignalStop, edgesBefore)))
                            break
    for signal in signalTimes.keys():
        signalTimes[signal] = sorted(signalTimes[signal])

    if options.debugSignal in signalTimes:
        debugInfo.sort()
        for t, info in debugInfo:
            print(info)
        busStops = set(
            [s.busStop for a, s in signalTimes[options.debugSignal]])
        arrivals = [a for a, s in signalTimes[options.debugSignal]]
        print(
            "Signal %s is passed %s times between %s and %s on approach to stops %s"
            % (options.debugSignal, len(arrivals), arrivals[0], arrivals[-1],
               ' '.join(busStops)))

    return signalTimes
Пример #3
0
def findInsertionConflicts(options, net, stopEdges, stopRoutes,
                           vehicleStopRoutes):
    """find routes that start at a stop with a traffic light at end of the edge
    and routes that pass this stop. Ensure
    insertion happens in the correct order"""
    # signal -> [(tripID, otherSignal, otherTripID, limit, line, otherLine, vehID, otherVehID), ...]
    conflicts = defaultdict(list)
    numConflicts = 0
    numIgnoredConflicts = 0
    for busStop, stops in stopRoutes.items():
        stopEdge = stopEdges[busStop]
        node = net.getEdge(stopEdge).getToNode()
        signal = node.getID()
        untils = []
        for edgesBefore, stop in stops:
            if stop.hasAttribute("until") and not options.untilFromDuration:
                until = parseTime(stop.until)
            elif stop.hasAttribute("arrival"):
                until = parseTime(stop.arrival) + parseTime(
                    stop.getAttributeSecure("duration", "0"))
            else:
                continue
            untils.append((until, edgesBefore, stop))
        # only use 'until' for sorting and keep the result stable otherwise
        untils.sort(key=itemgetter(0))
        prevPassing = None
        ignore = False
        for i, (nUntil, nEdges, nStop) in enumerate(untils):
            nVehStops = vehicleStopRoutes[nStop.vehID]
            nIndex = nVehStops.index((nEdges, nStop))
            nIsPassing = nIndex < len(nVehStops) - 1
            nIsDepart = len(nEdges) == 1
            if options.verbose and busStop == options.debugStop:
                print(i, "n:", humanReadableTime(nUntil), nStop.tripId,
                      nStop.vehID, nIndex, len(nVehStops), "passing:",
                      nIsPassing, "depart:", nIsDepart)
            if prevPassing is not None and nIsDepart:
                pUntil, pEdges, pStop = prevPassing
                pVehStops = vehicleStopRoutes[pStop.vehID]
                pIndex = pVehStops.index((pEdges, pStop))
                # no need to constrain subsequent departures (simulation should maintain ordering)
                if len(pEdges) > 1 or pIndex > 0:
                    # find edges after stop
                    if busStop == options.debugStop:
                        print(i, "p:", humanReadableTime(pUntil), pStop.tripId,
                              pStop.vehID, pIndex, len(pVehStops), "n:",
                              humanReadableTime(nUntil), nStop.tripId,
                              nStop.vehID, nIndex, len(nVehStops))
                    if nIsPassing:
                        # both vehicles move past the stop
                        pNextEdges = pVehStops[pIndex + 1][0]
                        nNextEdges = nVehStops[nIndex + 1][0]
                        limit = 1  # recheck
                        pSignal = signal
                        nSignal = signal
                        if node.getType() != "rail_signal":
                            # find signal in nextEdges
                            pSignal = findSignal(net, pNextEdges)
                            nSignal = findSignal(net, nNextEdges)
                            if pSignal is None or nSignal is None:
                                print((
                                    "Ignoring insertion conflict between %s and %s at stop '%s' "
                                    +
                                    "because no rail signal was found after the stop"
                                ) % (nStop.prevTripId, pStop.prevTripId,
                                     busStop),
                                      file=sys.stderr)
                                continue
                        # check for inconsistent ordering
                        if (ignore or
                            (options.abortUnordered
                             and pStop.hasAttribute("arrival")
                             and nStop.hasAttribute("arrival") and
                             (not options.ignoreParking or not parseBool(
                                 nStop.getAttributeSecure("parking", "false")))
                             and parseTime(pStop.arrival) > parseTime(
                                 nStop.arrival))):
                            numIgnoredConflicts += 1
                            # ignore conflict and any that follow
                            if not ignore:
                                # sort output by arrival again
                                print(
                                    "Found inconsistent times at stop %s "
                                    "for vehicle %s (%s, %s) and vehicle %s (%s, %s)"
                                    % (busStop, nStop.vehID,
                                       humanReadableTime(
                                           parseTime(nStop.arrival)),
                                       humanReadableTime(nUntil), pStop.vehID,
                                       humanReadableTime(
                                           parseTime(pStop.arrival)),
                                       humanReadableTime(pUntil)),
                                    file=sys.stderr)
                            ignore = True
                            continue
                        # predecessor tripId after stop is needed
                        pTripId = pStop.getAttributeSecure(
                            "tripId", pStop.vehID)
                        conflicts[nSignal].append((
                            nStop.prevTripId,
                            pSignal,
                            pTripId,
                            limit,
                            # attributes for adding comments
                            nStop.prevLine,
                            pStop.prevLine,
                            nStop.vehID,
                            pStop.vehID))
                        numConflicts += 1
                        if busStop == options.debugStop:
                            print(
                                "   found insertionConflict pSignal=%s nSignal=%s pTripId=%s"
                                % (pSignal, nSignal, pTripId)),

            if nIsPassing:
                prevPassing = (nUntil, nEdges, nStop)

    print("Found %s insertion conflicts" % numConflicts)
    if numIgnoredConflicts > 0:
        print("Ignored %s insertion conflicts" % (numIgnoredConflicts))
    return conflicts
Пример #4
0
def findConflicts(options, switchRoutes, mergeSignals, signalTimes):
    """find stops that target the same busStop from different branches of the
    prior merge switch and establish their ordering"""

    numConflicts = 0
    numIgnoredConflicts = 0
    # signal -> [(tripID, otherSignal, otherTripID, limit, line, otherLine, vehID, otherVehID), ...]
    conflicts = defaultdict(list)
    ignoredVehicles = set()
    for switch, stopRoutes2 in switchRoutes.items():
        numSwitchConflicts = 0
        numIgnoredSwitchConflicts = 0
        if switch == options.debugSwitch:
            print("Switch %s lies ahead of busStops %s" %
                  (switch, stopRoutes2.keys()))
        for busStop, stops in stopRoutes2.items():
            arrivals = []
            for edges, stop in stops:
                if stop.hasAttribute("arrival"):
                    arrival = parseTime(stop.arrival)
                elif stop.hasAttribute("until"):
                    arrival = parseTime(stop.until) - parseTime(
                        stop.getAttributeSecure("duration", "0"))
                else:
                    print(
                        "ignoring stop at %s without schedule information (arrival, until)"
                        % busStop)
                    continue
                arrivals.append((arrival, edges, stop))
            arrivals.sort(key=itemgetter(0))
            ignore = False
            for (pArrival, pEdges,
                 pStop), (nArrival, nEdges,
                          nStop) in zip(arrivals[:-1], arrivals[1:]):
                pSignal, pTimeSiSt = mergeSignals[(switch, pEdges)]
                nSignal, nTimeSiSt = mergeSignals[(switch, nEdges)]
                if switch == options.debugSwitch:
                    print(pSignal, nSignal, pStop, nStop)
                if pSignal != nSignal and pSignal is not None and nSignal is not None:
                    if (ignore or
                        (options.abortUnordered and pStop.hasAttribute("until")
                         and nStop.hasAttribute("until") and
                         (not options.ignoreParking or not parseBool(
                             pStop.getAttributeSecure("parking", "false")))
                         and parseTime(pStop.until) > parseTime(nStop.until))):
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        # ignore conflict and any that follow
                        if not ignore:
                            print(
                                "Found inconsistent times at stop %s "
                                "for vehicle %s (%s, %s) and vehicle %s (%s, %s)"
                                % (busStop, pStop.vehID,
                                   humanReadableTime(pArrival),
                                   humanReadableTime(parseTime(pStop.until)),
                                   nStop.vehID, humanReadableTime(nArrival),
                                   humanReadableTime(parseTime(nStop.until))),
                                file=sys.stderr)
                            # ignoredVehicles.insert(pStop.vehID)
                            ignoredVehicles.add(nStop.vehID)
                        ignore = True
                        continue
                    if (options.abortUnordered
                            and nStop.vehID in ignoredVehicles):
                        # no constraints for inconsistent vehicle to avoid deadlock
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        continue
                    if options.skipParking and parseBool(
                            nStop.getAttributeSecure("parking", "false")):
                        print(
                            "ignoring stop at %s for parking vehicle %s (%s, %s)"
                            %
                            (busStop, nStop.vehID, humanReadableTime(nArrival),
                             (humanReadableTime(parseTime(nStop.until))
                              if nStop.hasAttribute("until") else "-")))
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        continue
                    if options.skipParking and parseBool(
                            pStop.getAttributeSecure("parking", "false")):
                        print(
                            "ignoring stop at %s for %s (%s, %s) after parking vehicle %s (%s, %s)"
                            %
                            (busStop, nStop.vehID, humanReadableTime(nArrival),
                             (humanReadableTime(parseTime(nStop.until))
                              if nStop.hasAttribute("until") else "-"),
                             pStop.vehID, humanReadableTime(pArrival),
                             (humanReadableTime(parseTime(pStop.until))
                              if pStop.hasAttribute("until") else "-")))
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        continue

                    numConflicts += 1
                    numSwitchConflicts += 1
                    # check for trains that pass the switch in between the
                    # current two trains (heading to another stop) and raise the limit
                    limit = 1
                    pTimeAtSignal = pArrival - pTimeSiSt
                    nTimeAtSignal = nArrival - nTimeSiSt
                    end = nTimeAtSignal + options.delay
                    if options.verbose and options.debugSignal == pSignal:
                        print(
                            "check vehicles between %s and %s (including delay %s) at signal %s pStop=%s nStop=%s"
                            % (humanReadableTime(pTimeAtSignal),
                               humanReadableTime(end), options.delay, pSignal,
                               pStop, nStop))
                    limit += countPassingTrainsToOtherStops(
                        options, pSignal, busStop, pTimeAtSignal, end,
                        signalTimes)
                    conflicts[nSignal].append((
                        nStop.prevTripId,
                        pSignal,
                        pStop.prevTripId,
                        limit,
                        # attributes for adding comments
                        nStop.prevLine,
                        pStop.prevLine,
                        nStop.vehID,
                        pStop.vehID))
        if options.verbose:
            print("Found %s conflicts at switch %s" %
                  (numSwitchConflicts, switch))
            if numIgnoredSwitchConflicts > 0:
                print("Ignored %s conflicts at switch %s" %
                      (numIgnoredSwitchConflicts, switch))

    print("Found %s conflicts" % numConflicts)
    if numIgnoredConflicts > 0:
        print("Ignored %s conflicts" % numIgnoredConflicts)
    return conflicts
Пример #5
0
def findFoeInsertionConflicts(options, net, stopEdges, stopRoutes,
                              vehicleStopRoutes):
    """find routes that start at a stop with a traffic light at end of the edge
    and routes that pass this stop. Ensure insertion happens in the correct order
    (finds constrains on entering the stop segment ahead of insertion)
    """
    # signal -> [(tripID, otherSignal, otherTripID, limit, line, otherLine, vehID, otherVehID), ...]
    conflicts = defaultdict(list)
    numConflicts = 0
    numIgnoredConflicts = 0
    for busStop, stops in stopRoutes.items():
        if busStop == options.debugStop:
            print("findFoeInsertionConflicts at stop %s" % busStop)
        stopEdge = stopEdges[busStop]
        node = net.getEdge(stopEdge).getToNode()
        signal = node.getID()
        arrivals = []
        for edgesBefore, stop in stops:
            if stop.hasAttribute("arrival") and not options.untilFromDuration:
                arrival = parseTime(stop.until)
            elif stop.hasAttribute("until"):
                arrival = parseTime(stop.until) - parseTime(
                    stop.getAttributeSecure("duration", "0"))
            else:
                continue
            arrivals.append((arrival, edgesBefore, stop))
        # only use 'arrival' for sorting and keep the result stable otherwise
        arrivals.sort(key=itemgetter(0))
        prevDepart = None
        for i, (nArrival, nEdges, nStop) in enumerate(arrivals):
            nVehStops = vehicleStopRoutes[nStop.vehID]
            nIndex = nVehStops.index((nEdges, nStop))
            nIsPassing = nIndex < len(nVehStops) - 1
            nIsDepart = len(nEdges) == 1 and nIndex == 0
            if options.verbose and busStop == options.debugStop:
                print(i, "n:", humanReadableTime(nArrival), nStop.tripId,
                      nStop.vehID, nIndex, len(nVehStops), "passing:",
                      nIsPassing, "depart:", nIsDepart)
            if prevDepart is not None and nIsPassing and not nIsDepart:
                pArrival, pEdges, pStop = prevDepart
                pVehStops = vehicleStopRoutes[pStop.vehID]
                pIndex = pVehStops.index((pEdges, pStop))
                # no need to constrain subsequent passing (simulation should maintain ordering)
                if len(nEdges) > 1 or nIndex > 0:
                    # find edges after stop
                    if busStop == options.debugStop:
                        print(i, "p:", humanReadableTime(pArrival),
                              pStop.tripId, pStop.vehID,
                              pIndex, len(pVehStops), "n:",
                              humanReadableTime(nArrival), nStop.tripId,
                              nStop.vehID, nIndex, len(nVehStops))
                    # both vehicles move past the stop
                    pNextEdges = pVehStops[pIndex + 1][0]
                    limit = 1  # recheck
                    # insertion vehicle must pass signal after the stop
                    pSignal = signal
                    if node.getType() != "rail_signal":
                        # find signal in nextEdges
                        pSignal = findSignal(net, pNextEdges)
                        if pSignal is None:
                            print((
                                "Ignoring insertion foe conflict between %s and %s at stop '%s' "
                                +
                                "because no rail signal was found after the stop"
                            ) % (nStop.prevTripId, pStop.prevTripId, busStop),
                                  file=sys.stderr)
                            continue
                    # passing vehicle must wait before the stop
                    nPrevEdges = nVehStops[nIndex][0]
                    nSignal = findSignal(net, list(reversed(nPrevEdges)), True)
                    if nSignal is None:
                        print((
                            "Ignoring foe insertion conflict between %s and %s at stop '%s' "
                            +
                            "because no rail signal was found before the stop")
                              % (nStop.prevTripId, pStop.prevTripId, busStop),
                              file=sys.stderr)
                        continue

                    # check for inconsistent ordering
                    if pStop.getAttributeSecure("invalid", False):
                        numIgnoredConflicts += 1
                        continue

                    if options.skipParking:
                        if parseBool(
                                nStop.getAttributeSecure("parking", "false")):
                            print(
                                "ignoring stop at %s for parking vehicle %s (%s, %s)"
                                % (busStop, nStop.vehID,
                                   humanReadableTime(nArrival),
                                   (humanReadableTime(parseTime(nStop.until))
                                    if nStop.hasAttribute("until") else "-")))
                            numIgnoredConflicts += 1
                            continue
                        # if parseBool(pStop.getAttributeSecure("parking", "false")):
                        #    # additional check for until times
                        #    print("ignoring stop at %s for %s (%s, %s) after parking vehicle %s (%s, %s)" % (
                        #        busStop, nStop.vehID, humanReadableTime(nArrival),
                        #        (humanReadableTime(parseTime(nStop.until)) if nStop.hasAttribute("until") else "-"),
                        #        pStop.vehID, humanReadableTime(pArrival),
                        #        (humanReadableTime(parseTime(pStop.until)) if pStop.hasAttribute("until") else "-")))
                        #    numIgnoredConflicts += 1
                        #    continue

                    # hotfix for strange input
                    pNextStop = pVehStops[pIndex + 1][1]
                    if pNextStop.lane is not None:
                        print((
                            "Ignoring foe insertion conflict between %s and %s at stop '%s' "
                            +
                            "because the inserted train does not leave the stop edge (laneStop)"
                        ) % (nStop.prevTripId, pStop.prevTripId, busStop),
                              file=sys.stderr)
                        continue

                    # predecessor tripId after stop is needed
                    pTripId = pStop.getAttributeSecure("tripId", pStop.vehID)
                    conflicts[nSignal].append(
                        Conflict(
                            nStop.prevTripId,
                            pSignal,
                            pTripId,
                            limit,
                            # attributes for adding comments
                            nStop.prevLine,
                            pStop.prevLine,
                            nStop.vehID,
                            pStop.vehID,
                            nStop.arrival,
                            foeInsertion=True))
                    numConflicts += 1
                    if busStop == options.debugStop:
                        print(
                            "   found foe insertion conflict pSignal=%s nSignal=%s pVehId=%s pTripId=%s"
                            % (pSignal, nSignal, pStop.vehID, pTripId)),

            if nIsDepart and nIsPassing:
                prevDepart = (nArrival, nEdges, nStop)

    if numConflicts > 0:
        print("Found %s foe insertion conflicts" % numConflicts)
    if numIgnoredConflicts > 0:
        print("Ignored %s foe insertion conflicts" % (numIgnoredConflicts))
    return conflicts
Пример #6
0
def findConflicts(options, switchRoutes, mergeSignals, signalTimes):
    """find stops that target the same busStop from different branches of the
    prior merge switch and establish their ordering"""

    numConflicts = 0
    numRedundant = 0
    numIgnoredConflicts = 0
    numIgnoredStops = 0
    # signal -> [(tripID, otherSignal, otherTripID, limit, line, otherLine, vehID, otherVehID), ...]
    conflicts = defaultdict(list)

    for switch, stopRoutes2 in switchRoutes.items():
        numSwitchConflicts = 0
        numRedundantSwitchConflicts = 0
        numIgnoredSwitchConflicts = 0
        numIgnoredSwitchStops = 0
        if switch == options.debugSwitch:
            print("Switch %s lies ahead of busStops %s" %
                  (switch, stopRoutes2.keys()))
        for busStop, stops in stopRoutes2.items():
            arrivals = []
            for edges, stop in stops:
                if stop.hasAttribute("arrival"):
                    arrival = parseTime(stop.arrival)
                elif stop.hasAttribute("until"):
                    arrival = parseTime(stop.until) - parseTime(
                        stop.getAttributeSecure("duration", "0"))
                else:
                    print(
                        "ignoring stop at %s without schedule information (arrival, until)"
                        % busStop)
                    continue
                if stop.getAttributeSecure("invalid", False):
                    numIgnoredSwitchStops += 1
                    numIgnoredStops += 1
                    continue
                arrivals.append((arrival, edges, stop))
            arrivals.sort(key=itemgetter(0))
            arrivalsBySignal = defaultdict(list)
            for (pArrival, pEdges,
                 pStop), (nArrival, nEdges,
                          nStop) in zip(arrivals[:-1], arrivals[1:]):
                pSignal, pTimeSiSt = mergeSignals[(switch, pEdges)]
                nSignal, nTimeSiSt = mergeSignals[(switch, nEdges)]
                if switch == options.debugSwitch:
                    print(pSignal, nSignal, pStop, nStop)
                if pSignal != nSignal and pSignal is not None and nSignal is not None:
                    if options.skipParking and parseBool(
                            nStop.getAttributeSecure("parking", "false")):
                        print(
                            "ignoring stop at %s for parking vehicle %s (%s, %s)"
                            %
                            (busStop, nStop.vehID, humanReadableTime(nArrival),
                             (humanReadableTime(parseTime(nStop.until))
                              if nStop.hasAttribute("until") else "-")))
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        continue
                    if options.skipParking and parseBool(
                            pStop.getAttributeSecure("parking", "false")):
                        print(
                            "ignoring stop at %s for %s (%s, %s) after parking vehicle %s (%s, %s)"
                            %
                            (busStop, nStop.vehID, humanReadableTime(nArrival),
                             (humanReadableTime(parseTime(nStop.until))
                              if nStop.hasAttribute("until") else "-"),
                             pStop.vehID, humanReadableTime(pArrival),
                             (humanReadableTime(parseTime(pStop.until))
                              if pStop.hasAttribute("until") else "-")))
                        numIgnoredConflicts += 1
                        numIgnoredSwitchConflicts += 1
                        continue
                    numConflicts += 1
                    numSwitchConflicts += 1
                    # check for trains that pass the switch in between the
                    # current two trains (heading to another stop) and raise the limit
                    limit = 1
                    pTimeAtSignal = pArrival - pTimeSiSt
                    nTimeAtSignal = nArrival - nTimeSiSt
                    end = nTimeAtSignal + options.delay
                    if options.verbose and options.debugSignal == pSignal:
                        print(
                            "check vehicles between %s and %s (including delay %s) at signal %s pStop=%s nStop=%s"
                            % (humanReadableTime(pTimeAtSignal),
                               humanReadableTime(end), options.delay, pSignal,
                               pStop, nStop))
                    limit += countPassingTrainsToOtherStops(
                        options, pSignal, busStop, pTimeAtSignal, end,
                        signalTimes)
                    conflicts[nSignal].append(
                        Conflict(
                            nStop.prevTripId,
                            pSignal,
                            pStop.prevTripId,
                            limit,
                            # attributes for adding comments
                            nStop.prevLine,
                            pStop.prevLine,
                            nStop.vehID,
                            pStop.vehID,
                            nArrival))
                    if options.redundant >= 0:
                        prevBegin = pTimeAtSignal
                        for p2Arrival, p2Stop in reversed(
                                arrivalsBySignal[pSignal]):
                            if pArrival - p2Arrival > options.redundant:
                                break
                            numRedundant += 1
                            numRedundantSwitchConflicts += 1
                            p2TimeAtSignal = p2Arrival - pTimeSiSt
                            limit += 1
                            limit += countPassingTrainsToOtherStops(
                                options, pSignal, busStop, p2TimeAtSignal,
                                prevBegin, signalTimes)
                            conflicts[nSignal].append(
                                Conflict(
                                    nStop.prevTripId,
                                    pSignal,
                                    p2Stop.prevTripId,
                                    limit,
                                    # attributes for adding comments
                                    nStop.prevLine,
                                    p2Stop.prevLine,
                                    nStop.vehID,
                                    p2Stop.vehID,
                                    nArrival))
                            prevBegin = p2TimeAtSignal

                if pSignal is not None and not (
                        options.skipParking and parseBool(
                            pStop.getAttributeSecure("parking", "false"))):
                    arrivalsBySignal[pSignal].append((pArrival, pStop))

        if options.verbose:
            print("Found %s conflicts at switch %s" %
                  (numSwitchConflicts, switch))
            if numRedundantSwitchConflicts > 0:
                print("Found %s redundant conflicts at switch %s" %
                      (numRedundantSwitchConflicts, switch))

            if numIgnoredSwitchConflicts > 0 or numIgnoredSwitchStops > 0:
                print(
                    "Ignored %s conflicts and % stops at switch %s" %
                    (numIgnoredSwitchConflicts, numIgnoredSwitchStops, switch))

    print("Found %s conflicts" % numConflicts)
    if numRedundant > 0:
        print("Found %s redundant conflicts" % numRedundant)

    if numIgnoredConflicts > 0 or numIgnoredStops > 0:
        print("Ignored %s conflicts and %s stops" %
              (numIgnoredConflicts, numIgnoredStops))
    return conflicts
Пример #7
0
def markOvertaken(options, vehicleStopRoutes, stopRoutes):
    # mark stops that should not participate in constraint generation
    # once a vehice appears to be "overtaken" (based on inconsistent
    # arrival/until timing), all subsequent stops of that vehicle should no
    # longer be used for contraint generation
    for vehicle, stopRoute in vehicleStopRoutes.items():
        overtaken = False
        for i, (edgesBefore, stop) in enumerate(stopRoute):
            if not (stop.hasAttribute("arrival")
                    and stop.hasAttribute("until")):
                continue
            parking = parseBool(stop.getAttributeSecure("parking", "false"))
            if not overtaken:
                arrival = parseTime(stop.arrival)
                until = parseTime(stop.until)
                for edgesBefore2, stop2 in stopRoutes[stop.busStop]:
                    if stop2.vehID == stop.vehID:
                        continue
                    if not stop2.hasAttribute(
                            "arrival") or not stop2.hasAttribute("until"):
                        continue
                    parking2 = parseBool(
                        stop2.getAttributeSecure("parking", "false"))
                    hasParking = parking or parking2
                    arrival2 = parseTime(stop2.arrival)
                    until2 = parseTime(stop2.until)
                    # if parking stops have the same until-time their depart order
                    # is undefined so we could get deadlocks
                    if options.skipParking and hasParking and until != until2:
                        continue
                    if arrival2 > arrival and until2 < until:
                        overtaken = True
                        print(
                            ("Vehicle %s (%s, %s) overtaken by %s (%s, %s) " +
                             "at stop %s (index %s) and ignored afterwards") %
                            (stop.vehID, humanReadableTime(arrival),
                             humanReadableTime(until), stop2.vehID,
                             humanReadableTime(arrival2),
                             humanReadableTime(until2), stop.busStop, i),
                            file=sys.stderr)
                        break
                    elif until == until2 and hasParking:
                        overtaken = True
                        if stop.vehID < stop2.vehID:
                            # only warn once
                            print((
                                "Undefined departure at stop %s" +
                                " (index %s) for %svehicle %s (%s, %s)" +
                                " and %svehicle %s (%s, %s)." +
                                " No constraints will be generated for them afterwards"
                            ) % (
                                stop.busStop,
                                i,
                                'parking ' if parking else ' ',
                                stop.vehID,
                                humanReadableTime(arrival),
                                humanReadableTime(until),
                                'parking ' if parking2 else ' ',
                                stop2.vehID,
                                humanReadableTime(arrival2),
                                humanReadableTime(until2),
                            ),
                                  file=sys.stderr)
                        break

            if overtaken:
                # print("invalid veh=%s stop=%s arrival=%s until=%s" %
                #        (stop.vehID, stop.busStop,
                #            humanReadableTime(parseTime(stop.arrival)),
                #            humanReadableTime(parseTime(stop.until))))
                stop.setAttribute("invalid", True)
Пример #8
0
 def formatVehCode(code):
     time, veh = code
     if options.hrTime:
         time = humanReadableTime(time)
     return "%s (plan=%s)" % (veh, time)
Пример #9
0
def findConflicts(options, switchRoutes, mergeSignals, signalTimes):
    """find stops that target the same busStop from different branches of the
    prior merge switch and establish their ordering"""

    numConflicts = 0
    # signal -> [(tripID, otherSignal, otherTripID, limit, line, otherLine, vehID, otherVehID), ...]
    conflicts = defaultdict(list)
    for switch, stopRoutes2 in switchRoutes.items():
        numSwitchConflicts = 0
        if switch == options.debugSwitch:
            print("Switch %s lies ahead of busStops %s" %
                  (switch, stopRoutes2.keys()))
        for busStop, stops in stopRoutes2.items():
            arrivals = []
            for edges, stop in stops:
                if stop.hasAttribute("arrival"):
                    arrival = parseTime(stop.arrival)
                elif stop.hasAttribute("until"):
                    arrival = parseTime(stop.until) - parseTime(
                        stop.getAttributeSecure("duration", "0"))
                else:
                    print(
                        "ignoring stop at %s without schedule information (arrival, until)"
                        % busStop)
                    continue
                arrivals.append((arrival, edges, stop))
            arrivals.sort()
            for (pArrival, pEdges,
                 pStop), (nArrival, nEdges,
                          nStop) in zip(arrivals[:-1], arrivals[1:]):
                pSignal, pTimeSiSt = mergeSignals[(switch, pEdges)]
                nSignal, nTimeSiSt = mergeSignals[(switch, nEdges)]
                if switch == options.debugSwitch:
                    print(pSignal, nSignal, pStop, nStop)
                if pSignal != nSignal and pSignal is not None and nSignal is not None:
                    numConflicts += 1
                    numSwitchConflicts += 1
                    # check for trains that pass the switch in between the
                    # current two trains (heading to another stop) and raise the limit
                    limit = 1
                    pTimeAtSignal = pArrival - pTimeSiSt
                    nTimeAtSignal = nArrival - nTimeSiSt
                    end = nTimeAtSignal + options.delay
                    if options.verbose and options.debugSignal == pSignal:
                        print(
                            "check vehicles between %s and %s (including delay %s) at signal %s pStop=%s nStop=%s"
                            % (humanReadableTime(pTimeAtSignal),
                               humanReadableTime(end), options.delay, pSignal,
                               pStop, nStop))
                    limit += countPassingTrainsToOtherStops(
                        options, pSignal, busStop, pTimeAtSignal, end,
                        signalTimes)
                    conflicts[nSignal].append((
                        nStop.prevTripId,
                        pSignal,
                        pStop.prevTripId,
                        limit,
                        # attributes for adding comments
                        nStop.prevLine,
                        pStop.prevLine,
                        nStop.vehID,
                        pStop.vehID))
        if options.verbose:
            print("Found %s conflicts at switch %s" %
                  (numSwitchConflicts, switch))

    print("Found %s conflicts" % numConflicts)
    return conflicts