Search in sources :

Example 1 with Transition

use of com.bmw.hmm.Transition in project graphhopper by graphhopper.

the class MapMatching method computeViterbiSequence.

/**
 * Computes the most likely state sequence for the observations.
 */
private List<SequenceState<State, Observation, Path>> computeViterbiSequence(List<ObservationWithCandidateStates> timeSteps) {
    final HmmProbabilities probabilities = new HmmProbabilities(measurementErrorSigma, transitionProbabilityBeta);
    final ViterbiAlgorithm<State, Observation, Path> viterbi = new ViterbiAlgorithm<>();
    int timeStepCounter = 0;
    ObservationWithCandidateStates prevTimeStep = null;
    for (ObservationWithCandidateStates timeStep : timeSteps) {
        final Map<State, Double> emissionLogProbabilities = new HashMap<>();
        Map<Transition<State>, Double> transitionLogProbabilities = new HashMap<>();
        Map<Transition<State>, Path> roadPaths = new HashMap<>();
        for (State candidate : timeStep.candidates) {
            // distance from observation to road in meters
            final double distance = candidate.getSnap().getQueryDistance();
            emissionLogProbabilities.put(candidate, probabilities.emissionLogProbability(distance));
        }
        if (prevTimeStep == null) {
            viterbi.startWithInitialObservation(timeStep.observation, timeStep.candidates, emissionLogProbabilities);
        } else {
            final double linearDistance = distanceCalc.calcDist(prevTimeStep.observation.getPoint().lat, prevTimeStep.observation.getPoint().lon, timeStep.observation.getPoint().lat, timeStep.observation.getPoint().lon);
            for (State from : prevTimeStep.candidates) {
                for (State to : timeStep.candidates) {
                    final Path path = createRouter().calcPath(from.getSnap().getClosestNode(), to.getSnap().getClosestNode(), from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE, to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE);
                    if (path.isFound()) {
                        double transitionLogProbability = probabilities.transitionLogProbability(path.getDistance(), linearDistance);
                        Transition<State> transition = new Transition<>(from, to);
                        roadPaths.put(transition, path);
                        transitionLogProbabilities.put(transition, transitionLogProbability);
                    }
                }
            }
            viterbi.nextStep(timeStep.observation, timeStep.candidates, emissionLogProbabilities, transitionLogProbabilities, roadPaths);
        }
        if (viterbi.isBroken()) {
            fail(timeStepCounter, prevTimeStep, timeStep);
        }
        timeStepCounter++;
        prevTimeStep = timeStep;
    }
    return viterbi.computeMostLikelySequence();
}
Also used : Path(com.graphhopper.routing.Path) ViterbiAlgorithm(com.bmw.hmm.ViterbiAlgorithm) VirtualEdgeIteratorState(com.graphhopper.routing.querygraph.VirtualEdgeIteratorState) SequenceState(com.bmw.hmm.SequenceState) Transition(com.bmw.hmm.Transition)

Aggregations

SequenceState (com.bmw.hmm.SequenceState)1 Transition (com.bmw.hmm.Transition)1 ViterbiAlgorithm (com.bmw.hmm.ViterbiAlgorithm)1 Path (com.graphhopper.routing.Path)1 VirtualEdgeIteratorState (com.graphhopper.routing.querygraph.VirtualEdgeIteratorState)1