bool RODFNet::isFalseSource(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen, const RODFDetectorCon& detectors) const { if (seen.size() == 1000) { // !!! WRITE_WARNING("Quitting checking for being a false source for detector '" + det.getID() + "' due to seen edge limit."); return false; } seen.push_back(edge); if (edge != getDetectorEdge(det)) { // ok, we are at one of the edges coming behind if (hasDetector(edge)) { const std::vector<std::string>& dets = myDetectorsOnEdges.find(edge)->second; for (std::vector<std::string>::const_iterator i = dets.begin(); i != dets.end(); ++i) { if (detectors.getDetector(*i).getType() == SINK_DETECTOR) { return false; } if (detectors.getDetector(*i).getType() == BETWEEN_DETECTOR) { return false; } if (detectors.getDetector(*i).getType() == SOURCE_DETECTOR) { return true; } } } else { if (myAmInHighwayMode && edge->getSpeed() < 19.) { return false; } } } if (myApproachedEdges.find(edge) == myApproachedEdges.end()) { return false; } const ROEdgeVector& appr = myApproachedEdges.find(edge)->second; bool isall = false; for (size_t i = 0; i < appr.size() && !isall; i++) { //printf("checking %s->\n", appr[i].c_str()); bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end(); if (!had) { if (isFalseSource(det, appr[i], seen, detectors)) { isall = true; } } } return isall; }
bool RODFNet::isDestination(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen, const RODFDetectorCon& detectors) const { if (seen.size() == 1000) { // !!! WRITE_WARNING("Quitting checking for being a destination for detector '" + det.getID() + "' due to seen edge limit."); return false; } if (edge == getDetectorEdge(det)) { // maybe there is another detector at the same edge // get the list of this/these detector(s) const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second; for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) { if ((*i) == det.getID()) { continue; } const RODFDetector& sec = detectors.getDetector(*i); if (getAbsPos(sec) > getAbsPos(det)) { // ok, there is another detector on the same edge and it is // after this one -> no destination return false; } } } if (!hasApproached(edge)) { if (edge != getDetectorEdge(det)) { if (hasDetector(edge)) { return false; } } return true; } if (edge != getDetectorEdge(det)) { // ok, we are at one of the edges coming behind if (myAmInHighwayMode) { if (edge->getSpeed() >= 19.4) { if (hasDetector(edge)) { // we are still on the highway and there is another detector return false; } } } } if (myAmInHighwayMode) { if (edge->getSpeed() < 19.4 && edge != getDetectorEdge(det)) { if (hasDetector(edge)) { return true; } if (myApproachedEdges.find(edge)->second.size() > 1) { return true; } } } if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end() && myDetectorEdges.find(det.getID())->second != edge) { return false; } const ROEdgeVector& appr = myApproachedEdges.find(edge)->second; bool isall = true; size_t no = 0; seen.push_back(edge); for (size_t i = 0; i < appr.size() && isall; i++) { bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end(); if (!had) { if (!isDestination(det, appr[i], seen, detectors)) { no++; isall = false; } } } return isall; }
bool RODFNet::isSource(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen, const RODFDetectorCon& detectors, bool strict) const { if (seen.size() == 1000) { // !!! WRITE_WARNING("Quitting checking for being a source for detector '" + det.getID() + "' due to seen edge limit."); return false; } if (edge == getDetectorEdge(det)) { // maybe there is another detector at the same edge // get the list of this/these detector(s) const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second; for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) { if ((*i) == det.getID()) { continue; } const RODFDetector& sec = detectors.getDetector(*i); if (getAbsPos(sec) < getAbsPos(det)) { // ok, there is another detector on the same edge and it is // before this one -> no source return false; } } } // it's a source if no edges are approaching the edge if (!hasApproaching(edge)) { if (edge != getDetectorEdge(det)) { if (hasDetector(edge)) { return false; } } return true; } if (edge != getDetectorEdge(det)) { // ok, we are at one of the edges in front if (myAmInHighwayMode) { if (edge->getSpeed() >= 19.4) { if (hasDetector(edge)) { // we are still on the highway and there is another detector return false; } // the next is a hack for the A100 scenario... // We have to look into further edges herein edges const ROEdgeVector& appr = myApproachingEdges.find(edge)->second; size_t noOk = 0; size_t noFalse = 0; size_t noSkipped = 0; for (size_t i = 0; i < appr.size(); i++) { if (!hasDetector(appr[i])) { noOk++; } else { noFalse++; } } if ((noFalse + noSkipped) == appr.size()) { return false; } } } } if (myAmInHighwayMode) { if (edge->getSpeed() < 19.4 && edge != getDetectorEdge(det)) { // we have left the highway already // -> the detector will be a highway source if (!hasDetector(edge)) { return true; } } } if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end() && myDetectorEdges.find(det.getID())->second != edge) { return false; } // let's check the edges in front const ROEdgeVector& appr = myApproachingEdges.find(edge)->second; size_t noOk = 0; size_t noFalse = 0; size_t noSkipped = 0; seen.push_back(edge); for (size_t i = 0; i < appr.size(); i++) { bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end(); if (!had) { if (isSource(det, appr[i], seen, detectors, strict)) { noOk++; } else { noFalse++; } } else { noSkipped++; } } if (!strict) { return (noFalse + noSkipped) != appr.size(); } else { return (noOk + noSkipped) == appr.size(); } }
void RODFNet::revalidateFlows(const RODFDetector* detector, RODFDetectorFlows& flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) { { if (flows.knows(detector->getID())) { const std::vector<FlowDef>& detFlows = flows.getFlowDefs(detector->getID()); for (std::vector<FlowDef>::const_iterator j = detFlows.begin(); j != detFlows.end(); ++j) { if ((*j).qPKW > 0 || (*j).qLKW > 0) { return; } } } } // ok, there is no information for the whole time; // lets find preceding detectors and rebuild the flows if possible WRITE_WARNING("Detector '" + detector->getID() + "' has no flows.\n Trying to rebuild."); // go back and collect flows ROEdgeVector previous; { std::vector<IterationEdge> missing; IterationEdge ie; ie.depth = 0; ie.edge = getDetectorEdge(*detector); missing.push_back(ie); bool maxDepthReached = false; while (!missing.empty() && !maxDepthReached) { IterationEdge last = missing.back(); missing.pop_back(); ROEdgeVector approaching = myApproachingEdges[last.edge]; for (ROEdgeVector::const_iterator j = approaching.begin(); j != approaching.end(); ++j) { if (hasDetector(*j)) { previous.push_back(*j); } else { ie.depth = last.depth + 1; ie.edge = *j; missing.push_back(ie); if (ie.depth > 5) { maxDepthReached = true; } } } } if (maxDepthReached) { WRITE_WARNING(" Could not build list of previous flows."); } } // Edges with previous detectors are now in "previous"; // compute following ROEdgeVector latter; { std::vector<IterationEdge> missing; for (ROEdgeVector::const_iterator k = previous.begin(); k != previous.end(); ++k) { IterationEdge ie; ie.depth = 0; ie.edge = *k; missing.push_back(ie); } bool maxDepthReached = false; while (!missing.empty() && !maxDepthReached) { IterationEdge last = missing.back(); missing.pop_back(); ROEdgeVector approached = myApproachedEdges[last.edge]; for (ROEdgeVector::const_iterator j = approached.begin(); j != approached.end(); ++j) { if (*j == getDetectorEdge(*detector)) { continue; } if (hasDetector(*j)) { latter.push_back(*j); } else { IterationEdge ie; ie.depth = last.depth + 1; ie.edge = *j; missing.push_back(ie); if (ie.depth > 5) { maxDepthReached = true; } } } } if (maxDepthReached) { WRITE_WARNING(" Could not build list of latter flows."); return; } } // Edges with latter detectors are now in "latter"; // lets not validate them by now - surely this should be done // for each time step: collect incoming flows; collect outgoing; std::vector<FlowDef> mflows; int index = 0; for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) { FlowDef inFlow; inFlow.qLKW = 0; inFlow.qPKW = 0; inFlow.vLKW = 0; inFlow.vPKW = 0; // collect incoming { // !! time difference is missing for (ROEdgeVector::iterator i = previous.begin(); i != previous.end(); ++i) { const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(*i)->getFlows(); if (flows.size() != 0) { const FlowDef& srcFD = flows[index]; inFlow.qLKW += srcFD.qLKW; inFlow.qPKW += srcFD.qPKW; inFlow.vLKW += srcFD.vLKW; inFlow.vPKW += srcFD.vPKW; } } } inFlow.vLKW /= (SUMOReal) previous.size(); inFlow.vPKW /= (SUMOReal) previous.size(); // collect outgoing FlowDef outFlow; outFlow.qLKW = 0; outFlow.qPKW = 0; outFlow.vLKW = 0; outFlow.vPKW = 0; { // !! time difference is missing for (ROEdgeVector::iterator i = latter.begin(); i != latter.end(); ++i) { const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(*i)->getFlows(); if (flows.size() != 0) { const FlowDef& srcFD = flows[index]; outFlow.qLKW += srcFD.qLKW; outFlow.qPKW += srcFD.qPKW; outFlow.vLKW += srcFD.vLKW; outFlow.vPKW += srcFD.vPKW; } } } outFlow.vLKW /= (SUMOReal) latter.size(); outFlow.vPKW /= (SUMOReal) latter.size(); // FlowDef mFlow; mFlow.qLKW = inFlow.qLKW - outFlow.qLKW; mFlow.qPKW = inFlow.qPKW - outFlow.qPKW; mFlow.vLKW = (inFlow.vLKW + outFlow.vLKW) / (SUMOReal) 2.; mFlow.vPKW = (inFlow.vPKW + outFlow.vPKW) / (SUMOReal) 2.; mflows.push_back(mFlow); } static_cast<RODFEdge*>(getDetectorEdge(*detector))->setFlows(mflows); flows.setFlows(detector->getID(), mflows); }
void RODFNet::buildRoutes(RODFDetectorCon& detcont, bool keepUnfoundEnds, bool includeInBetween, bool keepShortestOnly, int maxFollowingLength) const { // build needed information first buildDetectorEdgeDependencies(detcont); // then build the routes std::map<ROEdge*, RODFRouteCont* > doneEdges; const std::vector< RODFDetector*>& dets = detcont.getDetectors(); for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) { ROEdge* e = getDetectorEdge(**i); if (doneEdges.find(e) != doneEdges.end()) { // use previously build routes (*i)->addRoutes(new RODFRouteCont(*doneEdges[e])); continue; } ROEdgeVector seen; RODFRouteCont* routes = new RODFRouteCont(); doneEdges[e] = routes; RODFRouteDesc rd; rd.edges2Pass.push_back(e); rd.duration_2 = (e->getLength() / e->getSpeed()); //!!!; rd.endDetectorEdge = 0; rd.lastDetectorEdge = 0; rd.distance = e->getLength(); rd.distance2Last = 0; rd.duration2Last = 0; rd.overallProb = 0; ROEdgeVector visited; visited.push_back(e); computeRoutesFor(e, rd, 0, keepUnfoundEnds, keepShortestOnly, visited, **i, *routes, detcont, maxFollowingLength, seen); //!!!routes->removeIllegal(illegals); (*i)->addRoutes(routes); // add routes to in-between detectors if wished if (includeInBetween) { // go through the routes const std::vector<RODFRouteDesc>& r = routes->get(); for (std::vector<RODFRouteDesc>::const_iterator j = r.begin(); j != r.end(); ++j) { const RODFRouteDesc& mrd = *j; SUMOReal duration = mrd.duration_2; SUMOReal distance = mrd.distance; // go through each route's edges ROEdgeVector::const_iterator routeend = mrd.edges2Pass.end(); for (ROEdgeVector::const_iterator k = mrd.edges2Pass.begin(); k != routeend; ++k) { // check whether any detectors lies on the current edge if (myDetectorsOnEdges.find(*k) == myDetectorsOnEdges.end()) { duration -= (*k)->getLength() / (*k)->getSpeed(); distance -= (*k)->getLength(); continue; } // get the detectors const std::vector<std::string>& dets = myDetectorsOnEdges.find(*k)->second; // go through the detectors for (std::vector<std::string>::const_iterator l = dets.begin(); l != dets.end(); ++l) { const RODFDetector& m = detcont.getDetector(*l); if (m.getType() == BETWEEN_DETECTOR) { RODFRouteDesc nrd; copy(k, routeend, back_inserter(nrd.edges2Pass)); nrd.duration_2 = duration;//!!!; nrd.endDetectorEdge = mrd.endDetectorEdge; nrd.lastDetectorEdge = mrd.lastDetectorEdge; nrd.distance = distance; nrd.distance2Last = mrd.distance2Last; nrd.duration2Last = mrd.duration2Last; nrd.overallProb = mrd.overallProb; nrd.factor = mrd.factor; ((RODFDetector&) m).addRoute(nrd); } } duration -= (*k)->getLength() / (*k)->getSpeed(); distance -= (*k)->getLength(); } } } } }
void RODFNet::computeRoutesFor(ROEdge* edge, RODFRouteDesc& base, int /*no*/, bool keepUnfoundEnds, bool keepShortestOnly, ROEdgeVector& /*visited*/, const RODFDetector& det, RODFRouteCont& into, const RODFDetectorCon& detectors, int maxFollowingLength, ROEdgeVector& seen) const { std::vector<RODFRouteDesc> unfoundEnds; std::priority_queue<RODFRouteDesc, std::vector<RODFRouteDesc>, DFRouteDescByTimeComperator> toSolve; std::map<ROEdge*, ROEdgeVector > dets2Follow; dets2Follow[edge] = ROEdgeVector(); base.passedNo = 0; SUMOReal minDist = OptionsCont::getOptions().getFloat("min-route-length"); toSolve.push(base); while (!toSolve.empty()) { RODFRouteDesc current = toSolve.top(); toSolve.pop(); ROEdge* last = *(current.edges2Pass.end() - 1); if (hasDetector(last)) { if (dets2Follow.find(last) == dets2Follow.end()) { dets2Follow[last] = ROEdgeVector(); } for (ROEdgeVector::reverse_iterator i = current.edges2Pass.rbegin() + 1; i != current.edges2Pass.rend(); ++i) { if (hasDetector(*i)) { dets2Follow[*i].push_back(last); break; } } } // do not process an edge twice if (find(seen.begin(), seen.end(), last) != seen.end() && keepShortestOnly) { continue; } seen.push_back(last); // end if the edge has no further connections if (!hasApproached(last)) { // ok, no further connections to follow current.factor = 1.; SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition()); if (minDist < cdist) { into.addRouteDesc(current); } continue; } // check for passing detectors: // if the current last edge is not the one the detector is placed on ... bool addNextNoFurther = false; if (last != getDetectorEdge(det)) { // ... if there is a detector ... if (hasDetector(last)) { if (!hasInBetweenDetectorsOnly(last, detectors)) { // ... and it's not an in-between-detector // -> let's add this edge and the following, but not any further addNextNoFurther = true; current.lastDetectorEdge = last; current.duration2Last = (SUMOTime) current.duration_2; current.distance2Last = current.distance; current.endDetectorEdge = last; if (hasSourceDetector(last, detectors)) { ///!!! //toDiscard.push_back(current); } current.factor = 1.; SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition()); if (minDist < cdist) { into.addRouteDesc(current); } continue; } else { // ... if it's an in-between-detector // -> mark the current route as to be continued current.passedNo = 0; current.duration2Last = (SUMOTime) current.duration_2; current.distance2Last = current.distance; current.lastDetectorEdge = last; } } } // check for highway off-ramps if (myAmInHighwayMode) { // if it's beside the highway... if (last->getSpeed() < 19.4 && last != getDetectorEdge(det)) { // ... and has more than one following edge if (myApproachedEdges.find(last)->second.size() > 1) { // -> let's add this edge and the following, but not any further addNextNoFurther = true; } } } // check for missing end connections if (!addNextNoFurther) { // ... if this one would be processed, but already too many edge // without a detector occured if (current.passedNo > maxFollowingLength) { // mark not to process any further WRITE_WARNING("Could not close route for '" + det.getID() + "'"); unfoundEnds.push_back(current); current.factor = 1.; SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition()); if (minDist < cdist) { into.addRouteDesc(current); } continue; } } // ... else: loop over the next edges const ROEdgeVector& appr = myApproachedEdges.find(last)->second; bool hadOne = false; for (size_t i = 0; i < appr.size(); i++) { if (find(current.edges2Pass.begin(), current.edges2Pass.end(), appr[i]) != current.edges2Pass.end()) { // do not append an edge twice (do not build loops) continue; } RODFRouteDesc t(current); t.duration_2 += (appr[i]->getLength() / appr[i]->getSpeed()); //!!! t.distance += appr[i]->getLength(); t.edges2Pass.push_back(appr[i]); if (!addNextNoFurther) { t.passedNo = t.passedNo + 1; toSolve.push(t); } else { if (!hadOne) { t.factor = (SUMOReal) 1. / (SUMOReal) appr.size(); SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition()); if (minDist < cdist) { into.addRouteDesc(t); } hadOne = true; } } } } // if (!keepUnfoundEnds) { std::vector<RODFRouteDesc>::iterator i; ConstROEdgeVector lastDetEdges; for (i = unfoundEnds.begin(); i != unfoundEnds.end(); ++i) { if (find(lastDetEdges.begin(), lastDetEdges.end(), (*i).lastDetectorEdge) == lastDetEdges.end()) { lastDetEdges.push_back((*i).lastDetectorEdge); } else { bool ok = into.removeRouteDesc(*i); assert(ok); UNUSED_PARAMETER(ok); // ony used for assertion } } } else { // !!! patch the factors } while (!toSolve.empty()) { // RODFRouteDesc d = toSolve.top(); toSolve.pop(); // delete d; } }
void RODFDetector::computeSplitProbabilities(const RODFNet* net, const RODFDetectorCon& detectors, const RODFDetectorFlows& flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) { if (myRoutes == 0) { return; } // compute edges to determine split probabilities const std::vector<RODFRouteDesc>& routes = myRoutes->get(); std::vector<RODFEdge*> nextDetEdges; std::set<ROEdge*> preSplitEdges; for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) { const RODFRouteDesc& rd = *i; bool hadSplit = false; for (ROEdgeVector::const_iterator j = rd.edges2Pass.begin(); j != rd.edges2Pass.end(); ++j) { if (hadSplit && net->hasDetector(*j)) { if (find(nextDetEdges.begin(), nextDetEdges.end(), *j) == nextDetEdges.end()) { nextDetEdges.push_back(static_cast<RODFEdge*>(*j)); } myRoute2Edge[rd.routename] = static_cast<RODFEdge*>(*j); break; } if (!hadSplit) { preSplitEdges.insert(*j); } if ((*j)->getNumSuccessors() > 1) { hadSplit = true; } } } std::map<ROEdge*, SUMOReal> inFlows; if (OptionsCont::getOptions().getBool("respect-concurrent-inflows")) { for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) { std::set<ROEdge*> seen(preSplitEdges); ROEdgeVector pending; pending.push_back(*i); seen.insert(*i); while (!pending.empty()) { ROEdge* e = pending.back(); pending.pop_back(); for (ROEdgeVector::const_iterator it = e->getPredecessors().begin(); it != e->getPredecessors().end(); it++) { ROEdge* e2 = *it; if (e2->getNumSuccessors() == 1 && seen.count(e2) == 0) { if (net->hasDetector(e2)) { inFlows[*i] += detectors.getAggFlowFor(e2, 0, 0, flows); } else { pending.push_back(e2); } seen.insert(e2); } } } } } // compute the probabilities to use a certain direction int index = 0; for (SUMOTime time = startTime; time < endTime; time += stepOffset, ++index) { mySplitProbabilities.push_back(std::map<RODFEdge*, SUMOReal>()); SUMOReal overallProb = 0; // retrieve the probabilities for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) { SUMOReal flow = detectors.getAggFlowFor(*i, time, 60, flows) - inFlows[*i]; overallProb += flow; mySplitProbabilities[index][*i] = flow; } // norm probabilities if (overallProb > 0) { for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) { mySplitProbabilities[index][*i] = mySplitProbabilities[index][*i] / overallProb; } } } }