我正在编写一个项目,将非确定性有限自动机转换为等效的确定性有限自动机。到目前为止,我有NFA的状态,字母,开始状态和接受状态的NFA.java超类和子类及其各自的转换方法。到目前为止,我的NFA.java类看起来像这样
class NFA {
NFAStates statesNFA;
NFAAlphabet alphabetNFA;
NFASState startstateNFA;
NFAAcceptStates acceptstatesNFA;
}
我的NFAStates.java,NFAAlphabet.java和NFAAcceptStates.java是字符串的LinkedHashSets,它们是从用户输入的数组中解析出来的。我的NFASState.java类是一个包含单个字符的数组。
我正在尝试找到一种准确存储转换函数的方法(网格显示哪些状态在某些输入时转到哪个状态)。有没有办法可以做到这一点,也许有一个n维数组?我还需要能够使用方法将此对象操作为DFA。
答案 0 :(得分:3)
更一般地说,您要问的是如何使用节点和它们之间的有针对边来表示网络。在您的情况下,节点是状态,边是转换。因此,我将在下面的答案中使用您的术语,但您可以轻松地使用节点和边缘,城市和道路等。
根据问题空间的各种特征,您有很多选择。这些假设转换不具有特征(例如成本,前置条件等),但如果它们确实如此,那么模型的微小改动将支持存储这些特征。
class State { private Set<State> transitions; }
class Transition { private State from; private State to; } Set<Transition> transitions;
Map<State, List<State>> transitions;
boolean[][] transitions;
您选择的其中一项将取决于您用于从NFA过渡到DFA的算法。我怀疑如果转换不在状态内,它会更容易,因此可能会将选项1排除在外。但是重置对你来说可能都是可行的。只需选择最适合您算法的那个。
答案 1 :(得分:2)
举办过渡的班级怎么样?
interface NFATransition {
NFAState apply(NFAState currentState, Object input);
}
public class SimpleNFATransition implements NFATransition {
private final NFAState fromState;
private final NFAState toState;
private final Object transitionOnInput;
public SimpleNFATransition(NFAState fromState, NFAState toState, Object transitionOnInput) {
this.fromState = fromState;
this.toState = toState;
this.transitionOnInput = transitionOnInput;
}
public NFAState apply(NFAState fromState, Object input) {
if (fromState.equals(this.fromState) && input.equals(transitionOnInput)) {
return toState;
} else {
return fromState;
}
}
}
枚举数组或列表中的转换。
NFATransition[] transitions = new NFATransition[]{ new SimpleNFATransition(...), ... }
然后在执行机器时,执行以下操作:
NFAState currentState = startstateNFA;
while (!currentState.equals(stopState)) {
for (NFATransition transition : transitions) {
currentState = transition.apply(currentState, input);
if (currentState.equals(stopState)) {
break;
}
}
}