public static void main(String[] args) {
    Fsm fsm = new Fsm();

    State s1 = fsm.addState("State1");
    State s2 = fsm.addState("State2");
    State s3 = fsm.addState("State3");
    State s4 = fsm.addState("State4");
    State s5 = fsm.addState("State5");
    State s6 = fsm.addState("State6");
    State s7 = fsm.addState("State7");
    State s8 = fsm.addState("State8");
    State s9 = fsm.addState("State9");
    State s10 = fsm.addState("State10");

    s1.addTransition(s2);
    s2.addTransition(s1);
    s2.addTransition(s3);
    s3.addTransition(s1);
    s3.addTransition(s4);
    s4.addTransition(s2);
    s4.addTransition(s5);
    s5.addTransition(s6);
    s5.addTransition(s9);
    s6.addTransition(s7);
    s6.addTransition(s8);
    s7.addTransition(s8);
    s8.addTransition(s2);
    s9.addTransition(s10);
    s10.addTransition(s2);

    List<State> states = fsm.getAllStates();

    Map<State, Integer> stateWeights = calculateWeights(states);
    for (State state : states) {
      System.out.println(state.getId() + " has weight: " + stateWeights.get(state));
    }
  }
  private static List<AbstractOperator> generateConstraintsBySubGraph(
      Fsm model, SubGraph subGraph) {
    List<AbstractOperator> operators = new ArrayList<AbstractOperator>();

    if (subGraph.getStart() == subGraph.getEnd()) {

      // Alle Pfade laufen wieder im gleichen Zustand zusammen
      AlwaysOperator op =
          new AlwaysOperator(new FutureOperator(new StateOperator(subGraph.getStart().getId())));
      operators.add(op);

      if (!subGraph.getSources(subGraph.getEnd()).contains(subGraph.getStart())) {

        // Wenn man im Anfangszustand startet, müssen die Vorgängerzustände des Endzustands vor dem
        // Endzustand selbst besucht werden.
        AlwaysOperator op2 =
            new AlwaysOperator(
                new IfThenOperator(
                    new StateOperator(subGraph.getStart().getId()),
                    new NextOperator(
                        new UntilOperator(
                            new NotOperator(new StateOperator(subGraph.getEnd().getId())),
                            getOrCombination(subGraph.getEnd().getSources())))));

        operators.add(op2);
      }
    } else if (subGraph.getSources(subGraph.getEnd()).contains(subGraph.getStart())) {
      // Sehr kleiner Subgraph, der mindestens einen Pad mit nur einer Transition hat.
    } else {
      // Größerer Subgraph, und der Startzustand ist ungleich dem Endzustand

      // Wenn man im Anfangszustand startet, wird man irgendwann im Endzustand landen.
      AlwaysOperator op =
          new AlwaysOperator(
              new IfThenOperator(
                  new StateOperator(subGraph.getStart().getId()),
                  new FutureOperator(new StateOperator(subGraph.getEnd().getId()))));

      operators.add(op);

      // Wenn man im Anfangszustand startet, wird mind. einer der Vorgängerzustände des Endzustands
      // irgendwann besucht.
      AlwaysOperator op1 =
          new AlwaysOperator(
              new IfThenOperator(
                  new StateOperator(subGraph.getStart().getId()),
                  new FutureOperator(getOrCombination(subGraph.getSources(subGraph.getEnd())))));

      operators.add(op1);

      // Wenn man im Anfangszustand startet, müssen die Vorgängerzustände des Endzustands vor dem
      // Endzustand selbst besucht werden.
      AlwaysOperator op2 =
          new AlwaysOperator(
              new IfThenOperator(
                  new StateOperator(subGraph.getStart().getId()),
                  new UntilOperator(
                      new NotOperator(new StateOperator(subGraph.getEnd().getId())),
                      getOrCombination(subGraph.getSources(subGraph.getEnd())))));

      operators.add(op2);

      // Wenn man im Anfangszustand startet, kann man keinen Zustand außerhalb des Subgraphs
      // besuchen bevor man den Endzustand erreicht.
      List<AbstractOperator> and = new ArrayList<AbstractOperator>();
      for (State state : model.getAllStates()) {
        if (subGraph.contains(state)) continue;
        and.add(new NotOperator(new StateOperator(state.getId())));
      }
      if (and.size() > 0) {
        AlwaysOperator op3 =
            new AlwaysOperator(
                new IfThenOperator(
                    new StateOperator(subGraph.getStart().getId()),
                    new UntilOperator(
                        getAndCombination(and), new StateOperator(subGraph.getEnd().getId()))));

        operators.add(op3);
      }
    }

    return operators;
  }