public void reduction_algorithim() { if (isAFD(Mylist) == false) { MessageBox.Show("It's not AFD, please enter an AFD"); return; } State_node[] vertical_states_arr = new State_node[Mylist.Count - 1]; State_node[] horizontal_states_arr = new State_node[Mylist.Count - 1]; List <array_node> Pair_states_list = new List <array_node>(); bool has_distinguibles = false; int cont = 0; //Lenar los dos arreglos unidimensionales foreach (State_node node in Mylist) { if (cont == 0) { horizontal_states_arr[cont] = node; } if (cont >= 1 && cont <= (Mylist.Count - 1)) { vertical_states_arr[cont - 1] = node; } if (cont >= 1 && cont != (Mylist.Count - 1)) { horizontal_states_arr[cont] = node; } cont++; } //Lenar la lista Pair states de onjetos state y marcar los distinguibles int contador = 0; for (int i = 0; i < horizontal_states_arr.Length; i++) { for (int j = 0; j < vertical_states_arr.Length; j++) { int num = j + contador; if (num < vertical_states_arr.Length) { array_node node = new array_node(); node.state1 = horizontal_states_arr[i]; node.state2 = vertical_states_arr[num]; if (vertical_states_arr[num].getFinal() == true && horizontal_states_arr[i].getFinal() == false || vertical_states_arr[num].getFinal() == false && horizontal_states_arr[i].getFinal() == true) { node.son_distinguibles = true; node.son_indistinguibles = false; node.mark = 0; has_distinguibles = true; } else { node.son_distinguibles = false; node.son_indistinguibles = true; node.mark = -1; } Pair_states_list.Add(node); } } contador++; } if (has_distinguibles == false) { MessageBox.Show("This AFD can't be minimized"); return; } //Algoritmo para marcar int to_s1; int to_s2; bool parar = false; while (parar != true) { contador = 0; parar = true; foreach (array_node Pair_item in Pair_states_list.ToList()) { //Si el par es indisitnguible(que tiene un espacio libre) y estam arcado con -1 if (Pair_item.mark == -1) { //Buscar las transiciones de el estado 1 y el estado 2 for (int i = 0; i < Pair_item.state1.get_trans().Count; i++) { for (int j = 0; j < Pair_item.state2.get_trans().Count; j++) { //Si estan leyendo la misma variable, buscar los To if (Pair_item.state1.get_trans()[i].getRead() == Pair_item.state2.get_trans()[j].getRead()) { //Buscar los dos estados que dieron de reulstado en el To foreach (array_node node in Pair_states_list) { //Si el nuevvo par de TO es un par de los que esta en la lista de pares to_s1 = Pair_item.state1.get_trans()[i].getTo(); to_s2 = Pair_item.state2.get_trans()[j].getTo(); if (to_s2 == to_s1) { break; } if (Pair_item.state1.get_trans()[i].getTo() == node.state1.getId() && Pair_item.state2.get_trans()[j].getTo() == node.state2.getId()) { if (node.mark >= 0) { Pair_states_list[contador].mark = node.mark + 1; parar = false; } break; } else if (Pair_item.state1.get_trans()[i].getTo() == node.state2.getId() && Pair_item.state2.get_trans()[j].getTo() == node.state1.getId()) { if (node.mark >= 0) { Pair_states_list[contador].mark = node.mark + 1; parar = false; } break; } } } } } } contador++; } } //Print Mark print_mark(Pair_states_list); //Create new states formed byte id = 0; string name = ""; float x = 0; float y = 0; bool initial = false; bool final = false; List <State_node> temp_list = Mylist; foreach (array_node Pair_item in Pair_states_list) { initial = false; final = false; //Si el par es equivalente if (Pair_item.mark == -1) { //Se concatena el nombre name = Pair_item.state1.getName() + "," + Pair_item.state2.getName(); x = Pair_item.state1.getX(); y = Pair_item.state1.getY(); //Si alguno del par es inicial if (Pair_item.state1.getInit() == true || Pair_item.state2.getInit() == true) { initial = true; } //Si alguno del par es final if (Pair_item.state1.getFinal() == true || Pair_item.state2.getFinal() == true) { final = true; } State_node node = new State_node(id, name, x, y, initial, final); foreach (Transition tran in Pair_item.state1.get_trans()) { tran.setFrom(id); if (tran.To_State_name == Pair_item.state1.getName() || tran.To_State_name == Pair_item.state2.getName()) { tran.To_State_name = name; } node.get_trans().Add(tran); } //Se agrega el nuevo nodo a una lista Minimized_list.Add(node); //Borro los nodos separados que ahora estan unidos de la lista temporal foreach (State_node item in temp_list.ToList()) { if (item.getName() == Pair_item.state1.getName() || item.getName() == Pair_item.state2.getName()) { temp_list.Remove(item); } } int numerito = 0; foreach (State_node node_in_list in temp_list.ToList()) { for (int i = 0; i < node_in_list.get_trans().Count; i++) { if (node_in_list.get_trans()[i].To_State_name == Pair_item.state1.getName()) { //chaka temp_list[numerito].get_trans()[i].To_State_name = name; } if (node_in_list.get_trans()[i].To_State_name == Pair_item.state2.getName()) { temp_list[numerito].get_trans()[i].To_State_name = name; } } numerito++; } id++; } else { continue; } } //Agregar los nodos restantes, los que estan separados foreach (State_node node_from_temp_list in temp_list) { //Agregar nuevo id a los nodos separados node_from_temp_list.setId(id); id++; Minimized_list.Add(node_from_temp_list); } //Agregar las transiciones a los nodos foreach (State_node node_in_minimized_list in Minimized_list) { foreach (Transition node_transition in node_in_minimized_list.get_trans()) { //Ponerle el nuevo From a los nodos, que tiene que cambiar porque su id cambio node_transition.setFrom(node_in_minimized_list.getId()); foreach (State_node node_searching in Minimized_list) { if (node_transition.To_State_name == node_searching.getName()) { node_transition.setTo(node_searching.getId()); } } } } MessageBox.Show("Automaton has been minimized"); }
public void fill_list(string file) { XmlDocument doc = new XmlDocument(); doc.Load(file); foreach (XmlNode node in doc.DocumentElement) { if (node.Name == "automaton") { foreach (XmlNode child in node.ChildNodes) { byte id = 0; string name = ""; float x_pos = 0, y_pos = 0; bool initial = false, final = false; if (child.Name == "state") { byte.TryParse(child.Attributes[0].InnerText, out id); //id name = child.Attributes[1].InnerText; //name foreach (XmlNode state_child in child.ChildNodes) { if (state_child.Name == "x") { float.TryParse(state_child.InnerText, out x_pos); } if (state_child.Name == "y") { float.TryParse(state_child.InnerText, out y_pos); } if (state_child.Name == "initial") { initial = true; } if (state_child.Name == "final") { final = true; } } State_node _node = new State_node(id, name, x_pos, y_pos, initial, final); Mylist.Add(_node); } if (child.Name == "transition") { byte from = 0, to = 0; string read = ""; foreach (XmlNode state_child in child.ChildNodes) { if (state_child.Name == "from") { byte.TryParse(state_child.InnerText, out from); } if (state_child.Name == "to") { byte.TryParse(state_child.InnerText, out to); } if (state_child.Name == "read") { read = state_child.InnerText; } } Transition state_transition = new Transition(from, to, read); transition_list.Add(state_transition); } } } } }