Endlicher Automat in c++, Der Automat

in Deutsch D-A-CH9 months ago

Im letzten Beitrag wurde die Zustandsklasse State erstellt, womit man einen Zustand erstellen konnte. Doch isolierte Zustände sind langweilig. Nun erstellen wir eine weitere Klasse FSM (Finite State Machine/endlicher Automat) um Zustandsübergänge zu ermöglichen und um letztenendes einen endlichen Automaten für die Prüfung von Wörtern zu erhalten.

Dafür benötigen wir eine Liste voller Zustände. Mit createState wird ein neuer Zustand in die Liste der Zustände eingefügt. Mit der Funktion connectStates werden Zustandsübergänge erstellt. Dabei wird zu einem Zustand state1 eine ausgehende Kante und zugleich bei einem Zustand state2 eine eingehende Kante hinzugefügt. Diese beiden Zustände haben nun einen Zustandsübergang.

Dieses Beispiel zeigt einen endlichen Automaten mit fünf Zuständen A,B,C,D und E. Desweiteren werden einige Zustände per Zustandsübergänge verbunden.
Ja, sehr Theorielastig das Thema. Das stammt ja auch aus der Theoretischen Informatik. Mit meiner genialen Zeichnung wird diese FSM dargestellt damit man sich darunter etwas vorstellen kann.

#include <iostream>
#include <vector>
#include <algorithm>

class State {
private:
    std::string _condition;
    std::vector<State> _incoming, _outgoing;
public:
    State(std::string condition) : _condition(condition) {
        _incoming = std::vector<State>();
        _outgoing = std::vector<State>();
    }
    void addIncomingEdge(State& state){
        _incoming.push_back(state);
    }
    void addOutgoingEdge(State& state){
        _outgoing.push_back(state);
    }
    std::string getCondition() const {
        return _condition;
    }
    std::vector<State> getIncomingEdges() const {
        return _incoming;
    }
    std::vector<State> getOutgoingEdges() const {
        return _outgoing;
    }
};

void operator<< (std::ostream& out, const State& state){
    out << "Name: " << state.getCondition() << "\n";
    out << "In: ";
    for(auto n = 0; n < state.getIncomingEdges().size(); n++){
        std::cout << state.getIncomingEdges()[n].getCondition() << ",";
    }
    out << '\n';
    out << "Out: ";
    for(auto n = 0; n < state.getOutgoingEdges().size(); n++){
        std::cout << state.getOutgoingEdges()[n].getCondition() << ",";
    }
    out << "\n\n";
}

class FSM {
private:
    std::vector<State> _states;
public:
    FSM() {
        _states = std::vector<State>();
    }

    void createState(std::string condition) {
        _states.push_back(State(condition));
    }

    void connectStates(std::string state1, std::string state2){
        uint idx1 = 0, idx2 = 0;
        auto s1 = std::find_if(_states.begin(), _states.end(), [&state1](State& s){return s.getCondition() == state1;});
        if(s1 != _states.end()){
            idx1 = std::distance(_states.begin(), s1);
        }
        auto s2 = std::find_if(_states.begin(), _states.end(), [&state2](State& s){return s.getCondition() == state2;});
        if(s2 != _states.end()){
            idx2 = std::distance(_states.begin(), s2);
        }
        _states[idx1].addOutgoingEdge(_states[idx2]);
        _states[idx2].addIncomingEdge(_states[idx1]);
    }

    void printFSM(){
        for(auto n = 0; n < _states.size(); n++){
            std::cout << _states[n];
        }
    }
};

int main(){
    FSM fsm = FSM();
    fsm.createState("A");
    fsm.createState("B");
    fsm.createState("C");
    fsm.createState("D");
    fsm.createState("E");
    fsm.connectStates("A","B");
    fsm.connectStates("B","C");
    fsm.connectStates("C","A");
    fsm.connectStates("A","A");
    fsm.connectStates("C","D");
    fsm.connectStates("D","B");
    fsm.connectStates("D","E");
    fsm.connectStates("B","E");
    fsm.connectStates("E","A");
    fsm.connectStates("E","E");
    fsm.printFSM();
}


Meine Superzeichnung eines vereinfachten endlichen Automaten

Sort:  

!invest_vote !LUV !PIZZA !wine !WITZ !LOLZ !HUGH

 9 months ago Reveal Comment