Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ public class OnlineViterbi extends TiViterbi {
public boolean isBrokenBefore;

// Current convergence point
private OnlineExtendedState currentRoot;
public OnlineExtendedState currentRoot;
// Previous convergence point
private OnlineExtendedState previousRoot;
public OnlineExtendedState previousRoot;

// Time diff between root and previous root
public int timeDelta;
// Starting insert position for global sequence after algorithm interruption
public int insertPosition;
public int windowSize;
private int lastCompressTime;


/**
* Constructs an OnlineViterbi instance with an initial insert position of zero.
Expand All @@ -50,6 +53,24 @@ public OnlineViterbi() {
previousRoot = null;
timeDelta = 0;
insertPosition = 0;
windowSize = 0;
lastCompressTime = 0;
}

/**
* Constructs an OnlineViterbi instance with an initial insert position of zero.
*/
public OnlineViterbi(int windowSize) {
stateList = new LinkedList<>();
sequenceStates = new ArrayList<>();
isConverge = false;
isBrokenBefore = false;
currentRoot = null;
previousRoot = null;
timeDelta = 0;
insertPosition = 0;
this.windowSize = windowSize;
lastCompressTime = 0;
}

/**
Expand All @@ -58,7 +79,7 @@ public OnlineViterbi() {
*
* @param insertPosition The starting insert position for the global sequence.
*/
public OnlineViterbi(int insertPosition) {
public OnlineViterbi(int insertPosition, int windowSize) {
stateList = new LinkedList<>();
sequenceStates = new ArrayList<>();
isConverge = false;
Expand All @@ -67,6 +88,8 @@ public OnlineViterbi(int insertPosition) {
previousRoot = null;
timeDelta = 0;
this.insertPosition = insertPosition;
this.windowSize = windowSize;
lastCompressTime = 0;
}

/**
Expand All @@ -76,7 +99,7 @@ public OnlineViterbi(int insertPosition) {
* @param insertPosition The starting insert position for the global sequence.
* @param isBrokenBefore A boolean indicating whether the algorithm was broken before this instance was created.
*/
public OnlineViterbi(int insertPosition, boolean isBrokenBefore) {
public OnlineViterbi(int insertPosition, int windowSize, boolean isBrokenBefore) {
stateList = new LinkedList<>();
sequenceStates = new ArrayList<>();
isConverge = false;
Expand All @@ -85,6 +108,8 @@ public OnlineViterbi(int insertPosition, boolean isBrokenBefore) {
previousRoot = null;
timeDelta = 0;
this.insertPosition = insertPosition;
this.windowSize = windowSize;
lastCompressTime = 0;
}


Expand All @@ -95,10 +120,10 @@ public OnlineViterbi(int insertPosition, boolean isBrokenBefore) {
* @param observation The current GPS observation.
* @param candidates List of candidate points for the current step.
* @param emissionLogProbabilities Map of emission log probabilities for candidate points.
* @param transitionLogProbabilities Map of transition log probabilities between candidate points.
* @param transitionLogProbabilities Map of transition log probabilities between candidate points.
* @param time The current time step.
* @throws IllegalStateException if the method is called without initializing
* with an observation or after an HMM break.
* with an observation or after an HMM break.
*/
public void nextStep(
GPSPoint observation,
Expand Down Expand Up @@ -141,7 +166,7 @@ public void nextStep(
* @param curCandidates List of current candidate points.
* @param message Map of state probabilities.
* @param emissionLogProbabilities Map of emission probabilities for each candidate.
* @param transitionLogProbabilities Map of transition probabilities between candidates.
* @param transitionLogProbabilities Map of transition probabilities between candidates.
* @param time The current time step.
* @return Results after forward extension, including updated state probabilities and states.
*/
Expand Down Expand Up @@ -259,14 +284,16 @@ else if (time > 1) {
current.setNumOfState(validStateCount);
}

// Compress unnecessary states
compress(time);
// Free up dummy states
freeDummyState(time);
// Check for convergence point and record local solutions
if (searchForNewRoot()) {
isConverge = true;
traceback();
if (time > this.windowSize + this.lastCompressTime) {
// Compress unnecessary states
compress(time);
// Free up dummy states
freeDummyState(time);
// Check for convergence point and record local solutions
if (searchForNewRoot()) {
isConverge = true;
traceback();
}
}
}

Expand Down Expand Up @@ -359,7 +386,7 @@ private boolean searchForNewRoot() {
OnlineExtendedState ancestor = null;

// Time difference between the current and previous convergence points
timeDelta = current.getTime();
int timeDelta = current.getTime();

while (current != null) {
if (current.getNumOfChild() >= 2) ancestor = current;
Expand All @@ -370,14 +397,19 @@ private boolean searchForNewRoot() {
if (currentRoot == null) {
currentRoot = ancestor;
timeDelta = timeDelta - ancestor.getTime();
return timeDelta != 0;
if (timeDelta == 0) return false;
else {
lastCompressTime = ancestor.getTime();
return true;
}
} else {
if (ancestor != currentRoot) {
timeDelta = timeDelta - ancestor.getTime();
if (timeDelta == 0) return false;
else {
previousRoot = currentRoot;
currentRoot = ancestor;
lastCompressTime = ancestor.getTime();
return true;
}
}
Expand All @@ -397,15 +429,20 @@ private void traceback() {
interLocalPath.add(new SequenceState(currentRoot.getState(), currentRoot.getObservation()));

int depth = isConvergedBefore() ? currentRoot.getTime() - previousRoot.getTime() - 1 : currentRoot.getTime();

timeDelta = depth;
depth = Math.min(windowSize, depth);

System.out.println("current root time: " + currentRoot.getTime());
System.out.println("previous root time: " + (isConvergedBefore() ? previousRoot.getTime() : 0));
ExtendedState current = currentRoot.getBackPointer();

for (int i = 0; i < depth; i++) {
interLocalPath.add(new SequenceState(current.getState(), current.getObservation()));
current = current.getBackPointer();
}

assert current == null || current.getState() == previousRoot.getState();
// assert current == null || current.getState() == previousRoot.getState();
System.out.println("local added sequence length: " + interLocalPath.size());
Collections.reverse(interLocalPath);
sequenceStates.addAll(interLocalPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ public MapMatchedTrajectory streamMapMatch(Trajectory trajectory) throws Algorit
* @return MapMatchedTrajectory after online matching
* @throws AlgorithmExecuteException In case of algorithm errors
*/
public MapMatchedTrajectory onlineStreamMapMatch(Trajectory trajectory) throws AlgorithmExecuteException {
public MapMatchedTrajectory onlineStreamMapMatch(Trajectory trajectory, int windowSize) throws AlgorithmExecuteException {

TimeStep previousTimeStep = null;
List<SequenceState> sequence = new ArrayList<>();
OnlineViterbi viterbi = new OnlineViterbi();
OnlineViterbi viterbi = new OnlineViterbi(windowSize);

int currentTime = 0;
int trajectorySize = trajectory.getGPSPointList().size();
Expand All @@ -148,7 +148,7 @@ public MapMatchedTrajectory onlineStreamMapMatch(Trajectory trajectory) throws A
currentTime = (viterbi.message == null) ? 0 : 1;
}

result = this.computeViterbiSequence(gpsPoint, sequence, previousTimeStep, viterbi, currentTime);
result = this.computeOnlineViterbiSequence(gpsPoint, sequence, previousTimeStep, viterbi, currentTime);

sequence = result._1();
previousTimeStep = result._2();
Expand Down Expand Up @@ -246,7 +246,7 @@ private Tuple3<List<SequenceState>, TimeStep, TiViterbi> computeViterbiSequence(
* @param time The current time index.
* @return A tuple containing the updated sequence, previous time step, and Viterbi object.
*/
private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSequence(
private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeOnlineViterbiSequence(
GPSPoint point,
List<SequenceState> seq,
TimeStep preTimeStep,
Expand All @@ -256,7 +256,6 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque
System.out.println("current time: " + time);
windowBearing.addPoint(point);
TimeStep currentTimeStep = this.createTimeStep(point); // Create time step with point and candidate set.

int convergeStartIndex = viterbi.getSequenceStates().size();

if (currentTimeStep == null) {
Expand All @@ -272,7 +271,7 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque
// System.out.println("======================================================");

// Record the start position for global sequence insertion.
viterbi = new OnlineViterbi(seq.size());
viterbi = new OnlineViterbi(seq.size(), viterbi.windowSize);
preTimeStep = null;
} else {
if (preTimeStep != null) {
Expand Down Expand Up @@ -309,7 +308,7 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque

if (viterbi.isBroken) {
// Handle the case where the Viterbi algorithm encounters an issue.
// System.out.println("Viterbi is broken.");
System.out.println("Viterbi is broken.");
// System.out.println("======================================================");
// System.out.println("Sequence length before traceback last part: " + seq.size());
//
Expand All @@ -325,7 +324,7 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque

seq.add(viterbi.computeMostLikelySequence().get(viterbi.computeMostLikelySequence().size() - 1));
// Record the start position for global sequence insertion.
viterbi = new OnlineViterbi(seq.size(), true);
viterbi = new OnlineViterbi(seq.size(), viterbi.windowSize, true);
viterbi.startWithInitialObservation(
currentTimeStep.getObservation(),
currentTimeStep.getCandidates(),
Expand All @@ -339,12 +338,13 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque
System.out.println("Sequence length before merging converge part: " + seq.size());

List<SequenceState> sequenceStates = viterbi.getSequenceStates();
int size = sequenceStates.size();

// Record converged sequence.
convergedSequence.addAll(sequenceStates.subList(convergeStartIndex, sequenceStates.size()));
convergedSequence.addAll(sequenceStates.subList(convergeStartIndex, size - 1));

int size = sequenceStates.size();
System.out.println("Local sequence length: " + size);
System.out.println("Insert position: " + viterbi.insertPosition);
System.out.println("Initial start index: " + viterbi.insertPosition);
System.out.println("Converge start index: " + convergeStartIndex);

// 之前算法没有发生过中断,第一次收敛的序列从[index==0]开始复制(初始化的元素需要添加)
Expand All @@ -353,26 +353,40 @@ private Tuple3<List<SequenceState>, TimeStep, OnlineViterbi> computeViterbiSeque
int isBrokenBefore = viterbi.isBrokenBefore ? 1 : 0;
convergeStartIndex = viterbi.isConvergedBefore() ? convergeStartIndex : isBrokenBefore;

for (int i = convergeStartIndex; i < size; i++) {
// The time difference from the start of the current convergent sequence to the left boundary of the window.
int lengthDelta = viterbi.isConvergedBefore() ? viterbi.timeDelta - 1: viterbi.timeDelta;
int offset = Math.max(lengthDelta - viterbi.windowSize, 0);

System.out.println("Time delta: " + viterbi.timeDelta);
System.out.println("Length delta: " + lengthDelta);
System.out.println("Insert offset: " + offset);
System.out.println("Sequence size: " + size);

for (int i = convergeStartIndex; i < size - 1; i++) {
// 算法中断前,从索引0开始复制,无需减1
// 算法中断后,从索引1开始复制,需要减1
int insertPosition = viterbi.isBrokenBefore ? i + viterbi.insertPosition - 1 : i + viterbi.insertPosition;
if (i == convergeStartIndex) System.out.println("insert position: " + insertPosition);
seq.set(insertPosition, sequenceStates.get(i));
int insertIndex = viterbi.isBrokenBefore ? i + viterbi.insertPosition - 1: i + viterbi.insertPosition;
insertIndex += offset;
if (i == convergeStartIndex) System.out.println("Insert start index: " + insertIndex);
seq.set(insertIndex, sequenceStates.get(i));
}

// Update offset
// viterbi.preInsertPosition += size - convergeStartIndex;
// Reset convergence state until the next convergence occurs.
viterbi.isConverge = false;
System.out.println("Sequence length after merging converge part: " + seq.size());
}

// if (seq.size() == 206) {
// System.out.println(206);
// }
// Find the candidate point with the maximum probability and add to the sequence.
CandidatePoint maxPoint = StreamMapMatcher.findMaxValuePoint(viterbi.message);
seq.add(new SequenceState(maxPoint, point));
}

System.out.println("After add current time point, sequence length: " + seq.size());
System.out.println("################################");
System.out.println("======================================================");

preTimeStep = currentTimeStep;
}
Expand Down
Loading