use of com.bmw.hmm.ViterbiAlgorithm 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();
}
Aggregations