七巧板复原算法之小结局——给出一个最大结果集

按:之所以用小结局而非大结局,因为笔者的解法并没有给出理论上的全部解,只是给出了大部分解法。

算法描述如下

#1 初始化
#完成七巧板组件的初始化以及盛放七巧板的容器的初始化;
#2 采用DFS 方法获得解集合并记录
#3 以图片方式输出结果

采用堆栈实现的复原核心伪代码如下:

       private void PutTPartInBox(TangramPartSet tgPartSet)
        {
            //1# prepare the components of the tangram 
			.....
           	// DFS to find a solution 
            while (!m_Stop)
            {
///##################################################################################
                #region 1 Take  a part from the lib , TAKE A NEW ONE FROM THE LIB 
                ///##################################################################################
                if (bTakeFromLib)
                {

                    curPart = tgPartSet.GetOtherPartFromLib(curFailedParts);
                    if (curPart != null)// if the lib is not empty
                    {
						InitialilizeTheComponents(); 
 
                        bTakeFromBox = false;// not take from the box 
                        bToNextBoxIdx = false;

                    else // there is no required component in the lib
                    {

                        bTakeFromBox = true;// should take the components from the box(stack)

                    }
                }
                ///##################################################################################
                #endregion 1 Take one part from the LIB 
                ///##################################################################################

                //##################################################################################
                #region 2 Take one part from the box(pop up) and addjust its position in the box.
                //##################################################################################
                if (bTakeFromBox)
                {
                    if (tgPartSet.CountInBox() > 0)
                    {
                        curPart = tgPartSet.TakeLastPartFromBox();

                    }
                    else
                    {
                        //MessageBox.Show("All of the scenarios have been tried, commission complete.");
                        break;

                    }

                }
                //##################################################################################
                #endregion 2 Take one part from the box 
                //##################################################################################

                #region //################# state check          ##########################

                curBoxPlg = curPart.m_Plg.usingBoxPlg;
                curPartPlg = curPart.m_Plg;

                var statePlgCnt = curPartPlg.SatePlgCount;
                var boxVtxCnt = curPartPlg.usingBoxPlg.Count();
                bool bPartIdxEnd = curPartPlg.StatePlgIndex >= statePlgCnt - 1;
                bool bBoxIdxEnd = curBoxPlg.usingIdx > boxVtxCnt - 1;


                if (!bPartIdxEnd)// Try next state part polygon , inner loop,  
                {
                    curPartPlg.StatePlgIndex++;
                }
                else
                {
                    if (!bBoxIdxEnd)//outer loop
                    {
                        curBoxPlg.usingIdx++;
                        curPartPlg.StatePlgIndex = 0;
                    }
                    else// all of the loop ended, put it to the lib and get another one 
                    {
                        AddFailedPartForStep(curPart, FailedPartsForStep, tgPartSet.GetCurStep());
                        curFailedParts = _GetFailedPartForCurStep();
                        bTakeFromLib = true;
                        bTakeFromBox = false;
                        tgPartSet.ReturnPartToLib(curPart);
                        exePath += "3 ->Take another one  " + string.Format("_{0} [{1}]_", curPart.m_No, _InBoxType());
                        continue;
                    }
                }

                #endregion //####################  state check    ##############################   

                ///##################################################################################
                #region 3 Begin to adjust(Match) the part in the box (addjust its positon)
                ///##################################################################################
			 bMounted = CMyPolygonTool.MatchPolygon(curPartPlg, tgPartSet.m_MainBoxPlg, out outPart, pbxTestingBox);// check if the component can be put in the box 
///##################################################################################
                #endregion 3 Begin to adjust the part in the box (addjust its positon)
                ///##################################################################################

                ///##################################################################################
                #region 4 The part can not be set in the box (not matched)
                ///##################################################################################
                if (!bMounted)// Not matched , continue to take out component from the box( stack pop)
                {

                    tgPartSet.PutPartInBox(curPart);//  Put it in the box,, just to make for a loop, notice the stattus has been changed

                    bTakeFromLib = false;
                    bTakeFromBox = true;
                    continue;

                }
                ///##################################################################################
                #endregion 4 The part can not be set in the box (not match)
                ///##################################################################################

                ///##################################################################################
                #region 5 The part CAN be set in the box (Matched)
                ///##################################################################################
                if (bMounted)// this one can be put in the box , calcula the remainning area and take another part from lib
                {

  
                    tgPartSet.PutPartInBox(curPart);//  Put it in the box , and go on to take next part ( any type)
                    bTakeFromLib = true;

                    // initilize the failed part for this new level 

                    if (FailedPartsForStep.TryGetValue(tgPartSet.GetCurStep(), out _))
                    {
                        FailedPartsForStep.Remove(tgPartSet.GetCurStep());
                    }
                    curFailedParts = "";
                    //######################################################
                    //######!!!!   Find One !!!!!!!!!!!     ################
                    //######################################################
                    if (tgPartSet.CountInBox() == tgPartSet.GetTotalParts())
                    {

   						RecordInReusltList();
 
                        bTakeFromLib = false;
                        bTakeFromBox = true;

                        continue;// succeed ,continue try to find another solution
                    }

                    //calculating the left area and get a new part to process 

                    //2.3#
                    bTakeFromBox = false;
                    curBoxPlg = newPlyLst[0];

                    bTakeFromLib = true;

                    continue;// mounted in the box, to get a new part

                }
///##################################################################################
                #endregion 5 The part CAN be set in the box (Matched)
                ///##################################################################################



            }

        }

说明:上述算法中有两个核心容器:Lib 用于存放七巧板组件,Box(Stack)用于摆放七巧板,如果Lib容器为空,则说明完成了一个摆放, 将结果记录下来;否则回退,尝试下一个摆放;摆放中用到了前文提到的各种判断以及剩余区域的计算。摆放时对七巧板进行了旋转和反转操作,力图模仿七巧板的真实摆放情况,摆放时的具体算法采用左下优先贴合的方法,实际上这样摆放之后会漏掉右上摆放的部分解。如图示:

在这里插入图片描述
在这里插入图片描述
这两种方法对应的结果是不一样的,这也是本解法不完备的地方。
笔者思考了解决办法,终极解法就是在剩余空腔的集合中再分别使用本方法进行DFS。这样程序结构稍微复杂一点,实际代码并没有实现。

部分界面参考

1、七巧板设计界面

在这里插入图片描述
笔者尝试解决的实际七巧板的组件如下:
在这里插入图片描述
解法探索探索界面
在这里插入图片描述
一共找到216 中解法(应该是不重复的), 部分解法截图如下
在这里插入图片描述

代码还有待完善,但是…再议吧、

MaraSun 与 BJFWDQ

抗疫人在继续,人生何其苦长。
人啊,何必跟人较劲呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值