public static void Search(ref string equ_str, out List <string> ans_str_list, int movMatch = 1, int max_ans_num = 10, double MAX_TIME = 3.0) { Equation root; str2ssd(ref equ_str, out root); List <Equation> ans_list; Search(ref root, out ans_list, movMatch, max_ans_num, MAX_TIME); ans_str_list = new List <string>(ans_list.Count); for (int i = 0; i < ans_list.Count; i++) { Equation src = ans_list[i]; string dest; if (ssd2str(ref src, out dest)) { ans_str_list.Add(dest); } } }
// Exist Function private static bool exist(ref List <Equation> equ_list, ref Equation obj) { bool flag = true; foreach (var equ in equ_list) { flag = true; for (int i = 0; i < equ.ssds.Count; i++) { flag = flag & equ.ssds[i] == obj.ssds[i]; if (equ.ssds[i] != obj.ssds[i]) { break; } } if (flag == true) { return(true); } } return(false); }
// Check if the equation is valid public static bool isValidEqu(string equ) { string left, right; Equation.splitEqu(ref equ, out left, out right); // no equal or no right expression if (right == "") { return(false); } // right expression must be an integer int _; if (!int.TryParse(right, out _)) { return(false); } // make sure the generate answer is not negative if (_ < 0) { return(false); } // try solve the left try { int ans = Expr.evaluate(left); // if answer is negative, then cannot be handled if (ans < 0) { return(false); } } catch (Exception) { return(false); } return(true); }
public static void str2ssd(ref string src, out Equation dest) { dest = new Equation(); str2ssd(ref src, out dest.ssds, out dest.optr); }
// Generate a puzzle, if found return true, else false public static bool GenerateSearch(ref Equation root, out Equation puzzle, int movMatch = 1) { root.Attribute = Action.Remove; puzzle = new Equation(); // Set up Open and Close Table List <Equation> Open = new List <Equation>(), Close = new List <Equation>(); // mark if the puzzle is found /* 深度优先搜索算法: */ //(1)把起始节点S 放到未扩展节点Open 表中。如果此节点为一目标节点,则得到一 //个解。 Open.Add(root); //(2)如果Open 为一空表,或ans_list数量超过一定范围,则失败退出。 while (Open.Count > 0) { //(3)把Open 中第一个节点n 从Open 表移到Closed 表。 Equation cur_equ = Open[0]; Open.RemoveAt(0); Close.Add(cur_equ); // Check if Open[0].depth < 2 * movMatch if (cur_equ.get_depth() > 2 * movMatch) { continue; } //(4)扩展节点n ,产生其全部(时间太长,如何改进)后裔,对后裔生成其祖先、属性,(检查是否与前序节点一样),并把它们放入Open 表的前端(末端的节点比前端 //的节点后移出)。如果没有后裔,则转向步骤(2)。 // 其中已经检查节点是否与祖父一样; List <Equation> children; randomExpand(cur_equ, out children); Open.InsertRange(0, children); //(5)如果后继节点中有任一个为目标节点,则求得一个解,判断其Attributes == Action.Remove && depth == 2*MovMatch, // 成功退出;否则,转向步骤(2)。 for (int i = 0; i < children.Count; i++) { Equation son = children[i]; // if "son" needs to be placed one match, algorithm continues! if (son.Attribute == Action.Place) { continue; } // if "son".depth != 2 * matches, then still not ending! if (son.get_depth() != 2 * movMatch) { continue; } // now check! if (isValidEqu(son)) { // Optional: check if the result are "strictly" valid if (matchDiff(ref root, ref son) != 2 * movMatch) { continue; } puzzle.ssds = new List <SSD>(son.ssds); puzzle.Attribute = Action.Remove; puzzle.optr = new Dictionary <int, char>(son.optr); return(true); } } } return(false); }
/* Search algorithm */ public static void Search(ref Equation root, out List <Equation> ans_list, int movMatch = 1, int max_ans_num = 10, double MAX_TIME = 3.0) { root.Attribute = Action.Remove; ans_list = new List <Equation>(); //start watch sw.Restart(); // Set up Open and Close Table List <Equation> Open = new List <Equation>(), Close = new List <Equation>(); /* 深度优先搜索算法: */ //(1)把起始节点S 放到未扩展节点Open 表中。如果此节点为一目标节点,则得到一 //个解。 Open.Add(root); if (isCorrect(root)) { ans_list.Add(root); } //(2)如果Open 为一空表,或ans_list数量超过一定范围,则失败退出。 while (Open.Count > 0 && ans_list.Count < max_ans_num) { // check timer if (sw.Elapsed.TotalSeconds > MAX_TIME) { sw.Stop(); return; } //(3)把Open 中第一个节点n 从Open 表移到Closed 表。 Equation cur_equ = Open[0]; Open.RemoveAt(0); Close.Add(cur_equ); // Check if Open[0].depth < 2 * movMatch if (cur_equ.get_depth() > 2 * movMatch) { continue; } //(4)扩展节点n ,产生其全部(时间太长,如何改进)后裔,对后裔生成其祖先、属性,(检查是否与前序节点一样),并把它们放入Open 表的前端(末端的节点比前端 //的节点后移出)。如果没有后裔,则转向步骤(2)。 // 其中已经检查节点是否与祖父一样; List <Equation> children; expand(cur_equ, out children); Open.InsertRange(0, children); //(5)如果后继节点中有任一个为目标节点,则求得一个解,判断其Attributes == Action.Remove && depth == 2*MovMatch, // 成功退出;否则,转向步骤(2)。 for (int i = 0; i < children.Count; i++) { Equation son = children[i]; // if "son" needs to be placed one match, algorithm continues! if (son.Attribute == Action.Place) { continue; } // if "son".depth != 2 * matches, then still not ending! if (son.get_depth() != 2 * movMatch) { continue; } // now check! if (isCorrect(son) && !exist(ref ans_list, ref son)) { ans_list.Add(son); } } } sw.Stop(); }
// expand with random seed private static void randomExpand(Equation father, out List <Equation> children) { expand(father, out children); Shuffle(ref children); }
public static bool ssd2str(ref Equation src, out string dest) { return(ssd2str(ref src.ssds, ref src.optr, out dest)); }