Object[] additionalContext, double minSequenceScore, BeamSearchContextGenerator<T> cg, SequenceValidator<T> validator) {
Heap<Sequence> prev = new ListHeap<Sequence>(size);
Heap<Sequence> next = new ListHeap<Sequence>(size);
Heap<Sequence> tmp;
prev.add(new Sequence());
if (additionalContext == null) {
additionalContext = EMPTY_ADDITIONAL_CONTEXT;
}
for (int i = 0; i < sequence.length; i++) {
int sz = Math.min(size, prev.size());
for (int sc = 0; prev.size() > 0 && sc < sz; sc++) {
Sequence top = prev.extract();
List<String> tmpOutcomes = top.getOutcomes();
String[] outcomes = tmpOutcomes.toArray(new String[tmpOutcomes.size()]);
String[] contexts = cg.getContext(i, sequence, outcomes, additionalContext);
double[] scores;
if (contextsCache != null) {
scores = (double[]) contextsCache.get(contexts);
if (scores == null) {
scores = model.eval(contexts, probs);
contextsCache.put(contexts,scores);
}
}
else {
scores = model.eval(contexts, probs);
}
double[] temp_scores = new double[scores.length];
for (int c = 0; c < scores.length; c++) {
temp_scores[c] = scores[c];
}
Arrays.sort(temp_scores);
double min = temp_scores[Math.max(0,scores.length-size)];
for (int p = 0; p < scores.length; p++) {
if (scores[p] < min)
continue; //only advance first "size" outcomes
String out = model.getOutcome(p);
if (validator.validSequence(i, sequence, outcomes, out)) {
Sequence ns = new Sequence(top, out, scores[p]);
if (ns.getScore() > minSequenceScore) {
next.add(ns);
}
}
}
if (next.size() == 0) {//if no advanced sequences, advance all valid
for (int p = 0; p < scores.length; p++) {
String out = model.getOutcome(p);
if (validator.validSequence(i, sequence, outcomes, out)) {
Sequence ns = new Sequence(top, out, scores[p]);
if (ns.getScore() > minSequenceScore) {
next.add(ns);
}
}
}
}