src/main/java/de/dfki/lt/loot/fsa/algo/MinimizationBrzowski.java
private static <EdgeInfo> int[] computeEquivalentVertices(
    AbstractAutomaton<EdgeInfo> graph, Comparator<EdgeInfo> comp) {

    int nodesLength = graph.getNumberOfVertices();
    BitSet notEquivalent = new BitSet(nodesLength * nodesLength);
    Graph<EdgeInfo> converse = graph.converseLazy();

    // check pairs of nodes for equivalence: they are not equivalent if:
    // - one of them is a final node and the other is not
    // - they have different outgoing edges
    for (int i = 0; i < nodesLength; i++) {
      if (graph.isVertex(i)) {
        // we can skip the case j == i since each node is obviously equivalent
        // with itself
        for (int j = 0; j < i; j++) {
          if (graph.isVertex(j)) {
            if (graph.isFinalState(i) != graph.isFinalState(j) ||
                ! equalEdgesByLabel(comp, graph.getOutEdges(i), graph.getOutEdges(j))){
              // nodes are not equivalent
              notEquivalent.set(j * nodesLength + i);
              // propagate the new found states difference through the rest of the
              // graph
              propagate(graph, converse, comp, i, j, notEquivalent);
            }
          }
        }
      }
    }

    /*
    // print matrix
    System.out.print("   ");
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
    }
    System.out.println();
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
      for (int j = 0; j <= i ; j++) {
        System.out.print(! notEquivalent.get(j * nodes.length + i) ? "X  ": "O  ");
      }
      System.out.println();
    }
    */

    // from the matrix, compute the representatives for each node:
    // this is the minimal node with which it is equivalent
    int[] representative = new int[nodesLength];
    representative[0] = 0;
    for (int i = 0; i < nodesLength; i++) {
      if (graph.isVertex(i)) {
        int j = 0;
        while (j <= i
               && graph.isVertex(j)
               && notEquivalent.get(j * nodesLength + i)) {
          j++ ;
        }
        representative[i] = j;
      }
    }

    /*
    // print representatives
    System.out.println();
    for (int i = 0; i< nodes.length; i++) {
      System.out.print(representative[i] + " ");
    }
    System.out.println();
    */
    return representative;
  }
/**
   * This computes the equvalent classes from the given nodes.
   *
   * @param nodes an array of <code>Vertex</code>s
   * @return an array of <code>int</code>s that contains the node number of the
   * equivalence class representative for each node; if representative[i] == i,
   * node i is one of the representatives; if representative[i] == j, then node
   * j is the representative of the equivalence class i belongs to
   */
This computes the equvalent classes from the given nodes.
@param nodes an array of Vertexs
@return an array of ints that contains the node number of the
equivalence class representative for each node; if representative[i] == i,
node i is one of the representatives; if representative[i] == j, then node
j is the representative of the equivalence class i belongs to
This computes the equvalent classes from the given nodes . @param nodes an array of Vertexs @return an array of ints that contains the node number of the equivalence class representative for each node ; if representative [ i ] == i node i is one of the representatives ; if representative [ i ] == j then node j is the representative of the equivalence class i belongs to
private static <EdgeInfo> int[] computeEquivalentVertices(
    AbstractAutomaton<EdgeInfo> graph, Comparator<EdgeInfo> comp) {
    int nodesLength = graph.getNumberOfVertices();
    BitSet notEquivalent = new BitSet(nodesLength * nodesLength);
    Graph<EdgeInfo> converse = graph.converseLazy();
    for (int i = 0; i < nodesLength; i++) {
      if (graph.isVertex(i)) {
        for (int j = 0; j < i; j++) {
          if (graph.isVertex(j)) {
            if (graph.isFinalState(i) != graph.isFinalState(j) ||
                ! equalEdgesByLabel(comp, graph.getOutEdges(i), graph.getOutEdges(j))){
              notEquivalent.set(j * nodesLength + i);
              propagate(graph, converse, comp, i, j, notEquivalent);
            }
          }
        }
      }
    }
    /*
    // print matrix
    System.out.print("   ");
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
    }
    System.out.println();
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
      for (int j = 0; j <= i ; j++) {
        System.out.print(! notEquivalent.get(j * nodes.length + i) ? "X  ": "O  ");
      }
      System.out.println();
    }
    */
    int[] representative = new int[nodesLength];
    representative[0] = 0;
    for (int i = 0; i < nodesLength; i++) {
      if (graph.isVertex(i)) {
        int j = 0;
        while (j <= i
               && graph.isVertex(j)
               && notEquivalent.get(j * nodesLength + i)) {
          j++ ;
        }
        representative[i] = j;
      }
    }
    /*
    // print representatives
    System.out.println();
    for (int i = 0; i< nodes.length; i++) {
      System.out.print(representative[i] + " ");
    }
    System.out.println();
    */
    return representative;
  }
private static < EdgeInfo > int [ ] computeEquivalentVertices ( AbstractAutomaton < EdgeInfo > graph , Comparator < EdgeInfo > comp ) { int nodesLength = graph . getNumberOfVertices ( ) ; BitSet notEquivalent = new BitSet ( nodesLength * nodesLength ) ; Graph < EdgeInfo > converse = graph . converseLazy ( ) ; for ( int i = 0 ; i < nodesLength ; i ++ ) { if ( graph . isVertex ( i ) ) { for ( int j = 0 ; j < i ; j ++ ) { if ( graph . isVertex ( j ) ) { if ( graph . isFinalState ( i ) != graph . isFinalState ( j ) || ! equalEdgesByLabel ( comp , graph . getOutEdges ( i ) , graph . getOutEdges ( j ) ) ) { notEquivalent . set ( j * nodesLength + i ) ; propagate ( graph , converse , comp , i , j , notEquivalent ) ; } } } } } /*
    // print matrix
    System.out.print("   ");
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
    }
    System.out.println();
    for (int i = 0; i < nodes.length; i++) {
      System.out.format("%-3d", i);
      for (int j = 0; j <= i ; j++) {
        System.out.print(! notEquivalent.get(j * nodes.length + i) ? "X  ": "O  ");
      }
      System.out.println();
    }
    */ int [ ] representative = new int [ nodesLength ] ; representative [ 0 ] = 0 ; for ( int i = 0 ; i < nodesLength ; i ++ ) { if ( graph . isVertex ( i ) ) { int j = 0 ; while ( j <= i && graph . isVertex ( j ) && notEquivalent . get ( j * nodesLength + i ) ) { j ++ ; } representative [ i ] = j ; } } /*
    // print representatives
    System.out.println();
    for (int i = 0; i< nodes.length; i++) {
      System.out.print(representative[i] + " ");
    }
    System.out.println();
    */ return representative ; }
This computes the equvalent classes from the given nodes.
This computes the equvalent classes from the given nodes .
// check pairs of nodes for equivalence: they are not equivalent if: // - one of them is a final node and the other is not // - they have different outgoing edges // we can skip the case j == i since each node is obviously equivalent // with itself // nodes are not equivalent // propagate the new found states difference through the rest of the // graph // from the matrix, compute the representatives for each node: // this is the minimal node with which it is equivalent