code: private int[] predictForwardBackward(int[][] x) {
          int n = x.length; // length of sequence
  
          TrellisNode[][] trellis = getTrellis(x);
          double[] scaling = new double[n];
          forward(trellis, scaling);
          backward(trellis);
  
          int[] label = new int[n];
          double[] p = new double[numClasses];
          for (int i = 0; i < n; i++) {
              TrellisNode[] ti = trellis[i];
              for (int j = 0; j < numClasses; j++) {
                  TrellisNode tij = ti[j];
                  p[j] = tij.alpha * tij.beta;
              }
  
              double max = Double.NEGATIVE_INFINITY;
              for (int j = 0; j < numClasses; j++) {
                  if (max < p[j]) {
                      max = p[j];
                      label[i] = j;
                  }
              }
          }
  
          return label;
      }
docs: Returns the most likely label sequence given the feature sequence by the
  forward-backward algorithm.
  
  @param x a sequence of sparse features taking values in [0, p) about each
  position of original sequence, where p is the number of features.
  @return the most likely label sequence.