Beispiel #1
0
        // check if the grandson has the same list as its grandpa!
        private static bool sameAsGrandpa(Equation p, int ssd_idx)
        {
            // if p is in the first 2 layers, then he does not have grandpa
            if (p.get_depth() < 2)
            {
                return(false);
            }
            Equation grandpa = p.anncestors[1];

            return(p.ssds[ssd_idx] == grandpa.ssds[ssd_idx]);
        }
Beispiel #2
0
        // expand One Possible random equation List, define its ancestors, attribute, ssds and optr
        private static void expand(Equation father, out List <Equation> children)
        {
            children = new List <Equation>();

            for (int i = 0; i < father.ssds.Count; i++)
            {
                SSD cur_ssd = father.ssds[i];

                // expand curent ssd
                var cur_ssd_list = cur_ssd.expand(father.Attribute);

                for (int j = 0; j < cur_ssd_list.Count; j++)
                {
                    Equation son = new Equation();
                    // ssds
                    son.ssds = new List <SSD>(father.ssds);
                    // change the i'th ssd to a new one.
                    son.ssds[i] = cur_ssd_list[j];

                    // optr
                    son.optr = new Dictionary <int, char>(father.optr);
                    // attribute
                    son.Attribute = inverse(father.Attribute);
                    // ancestors
                    son.anncestors = new List <Equation>(father.anncestors);
                    son.anncestors.Insert(0, father);

                    //* Cut branch Operation*/
                    // if same as grandpa: (means it goes back! ) then should be cut!
                    if (sameAsGrandpa(son, i))
                    {
                        continue;
                    }
                    // if the son's depth = 3, and son's ssds[i] == grandpa's ssds[i], then cut!
                    if (father.get_depth() == 2 && son.ssds[i] == father.anncestors[0].ssds[i])
                    {
                        continue;
                    }

                    children.Add(son);
                }
            }
        }
Beispiel #3
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);
        }
Beispiel #4
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();
        }