예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        // 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);
        }
예제 #4
0
 public static void str2ssd(ref string src, out Equation dest)
 {
     dest = new Equation();
     str2ssd(ref src, out dest.ssds, out dest.optr);
 }
예제 #5
0
        // 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);
        }
예제 #6
0
        /* 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();
        }
예제 #7
0
 // expand with random seed
 private static void randomExpand(Equation father, out List <Equation> children)
 {
     expand(father, out children);
     Shuffle(ref children);
 }
예제 #8
0
 public static bool ssd2str(ref Equation src, out string dest)
 {
     return(ssd2str(ref src.ssds, ref src.optr, out dest));
 }