public void tag(Sentence src) throws IOException {
		src.clearTags();
		LogPrinter logger = LogUtils.getLogger();
		final int len = src.size();
		TagList paths = dict.getTagList(src);
		TagState nextNode, preNode;
		double min, min_temp;
		for (int i = 1; i < len - 1; i++) {
			for (int j = 0; j < paths.lists[i].length; j++) {
				nextNode = paths.lists[i][j];
				for (Entry<String, Path> entry : nextNode.paths.entrySet()) {
					min = Double.MAX_VALUE;
					for (int k = 0; k < paths.lists[i - 1].length; k++) {
						preNode = paths.lists[i - 1][k];
						min_temp = preNode.paths.get(nextNode.state).value
								+ dict.H(preNode.state, nextNode.state,
										entry.getKey());
						if (min_temp < min) {
							min = min_temp;
							entry.getValue().pre = k;
						}
					}
					entry.getValue().value += min;
				}
			}
		}

		String next = Tag.SE;
		int best = 0;
		min = Double.MAX_VALUE;
		nextNode = paths.lists[len - 1][best];
		Path bestPath = nextNode.paths.get(next);
		for (int i = 0; i < paths.lists[len - 2].length; i++) {
			preNode = paths.lists[len - 2][i];
			min_temp = preNode.paths.get(nextNode.state).value;
			if (min_temp < min) {
				min = min_temp;
				bestPath.pre = i;
			}
		}
		bestPath.value = min;
		logger.log(new Explainable.StringExplain("minPathValue=" + min),
				"best path value");
		logger.log(new tagPathMap(paths, src), "Tag Map paths");

		nextNode = paths.lists[len - 1][best];
		src.get(len - 1).tag = nextNode.state;
		best = nextNode.paths.get(next).pre;
		next = nextNode.state;
		for (int i = len - 2; i > -1; i--) {
			nextNode = paths.lists[i][best];
			src.get(i).tag= nextNode.state;
			best = nextNode.paths.get(next).pre;
			next = nextNode.state;
		}
	}