コード例 #1
0
ファイル: FSA.java プロジェクト: 2016bmw/zr-learning
  private void mergeIntermediateStates() {
    Map<Adjacency, Set<FSANode>> adjToNodes = new HashMap<>();
    Set<FSANode> newCurMergeLevel = new HashSet<>();
    Map<FSANode, FSANode> formerNodeToMergedNode = new HashMap<>();
    for (FSANode node : curMergeLevel) {
      boolean needToBreak = false;
      for (Set<FSANode> targets : node.getLabelToTargets().values()) {
        if (targets.size() > 1) {
          updateBasedOnMerges(targets, formerNodeToMergedNode);
          FSANode newNode = mergeNodes(targets);
          targets.stream().forEach(n -> formerNodeToMergedNode.put(n, newNode));
          if (newNode.needsToMergeOutgoingEdges()) {
            newCurMergeLevel.add(newNode);
          }
          needToBreak = true;
        }
      }

      if (needToBreak) {
        break;
      }

      for (FSAEdge edge : node.getOutgoingEdges()) {
        Adjacency adj = new Adjacency(edge);
        Set<FSANode> nodesWithSameLabelToSameTarget = adjToNodes.get(adj);
        if (nodesWithSameLabelToSameTarget == null) {
          nodesWithSameLabelToSameTarget = new HashSet<>();
          adjToNodes.put(adj, nodesWithSameLabelToSameTarget);
        }
        nodesWithSameLabelToSameTarget.add(node);
      }
    }

    for (FSANode node : curMergeLevel) {
      newCurMergeLevel.addAll(
          node.getIncomingEdges().stream().map(e -> e.getSource()).collect(Collectors.toSet()));
    }

    for (Set<FSANode> nodes : adjToNodes.values()) {
      updateBasedOnMerges(nodes, formerNodeToMergedNode);
      if (nodes.size() > 1) {
        FSANode newNode = mergeNodes(nodes);
        if (!Collections.disjoint(newCurMergeLevel, nodes)) {
          newCurMergeLevel.removeAll(nodes);
          newCurMergeLevel.add(newNode);
        }
        for (FSANode node : nodes) {
          formerNodeToMergedNode.put(node, newNode);
        }
      }
    }
    // remove any nodes that are now contained by other nodes
    curMergeLevel =
        newCurMergeLevel.stream().filter(n -> this.nodes.contains(n)).collect(Collectors.toSet());
  }