public DancingLinksNode(DancingLinksColumnHeader h, int cellx, int celly, int cellnum)
 {
     row    = new Triple <int>(cellx, celly, cellnum);
     header = h;
 }
Beispiel #2
0
        public bool dancingLinksAlg()
        {
            if (columns.Count == 0)
            {
                return(true);
            }

            int minCount = columns.Min(x => x.columnMemberCount);

            if (minCount <= 0)
            {
                return(false);
            }

            DancingLinksColumnHeader c = columns.Where(x => x.columnMemberCount == minCount).ToArray()[0];
            int count = c.columnMemberCount;
            DancingLinksNode curNode = c.firstEntry;


            //Outer loop iterates through rows intersecting the column

            //Inside this, we look at a given row. Iterate through the columns intersecting that row.


            while (count > 0)
            {
                #region Removal_and_Test
                DancingLinksNode curColPivot = curNode.right;

                while (curColPivot != curNode)
                {
                    DancingLinksNode curRowPivot = curColPivot.down;

                    while (curRowPivot != curColPivot)
                    {
                        #region Remove_rows_Except_Pivot_Row
                        DancingLinksNode curRemNode = curRowPivot.right;
                        while (curRemNode != curRowPivot)
                        {
                            curRemNode.up.down = curRemNode.down;
                            curRemNode.down.up = curRemNode.up;

                            curRemNode.header.columnMemberCount--;

                            curRemNode = curRemNode.right;
                        }

                        rows.Remove(rowLookUp[curRowPivot.row]);
                        #endregion

                        //curRowPivot.right.left = curRowPivot.left;
                        //curRowPivot.left.right = curRowPivot.right;

                        curRowPivot = curRowPivot.down;
                    }

                    columns.Remove(curColPivot.header);

                    //We must remove the Pivot Row as well.
                    //Notice that we do not remove the Pivot Row from the rows list. This is intentional.
                    curColPivot.up.down = curColPivot.down;
                    curColPivot.down.up = curColPivot.up;

                    curColPivot = curColPivot.right;
                }

                //Lastly, we remove the pivot column.
                columns.Remove(curNode.header);

                curNode.left.right = curNode.right;
                curNode.right.left = curNode.left;

                DancingLinksNode colRemNode = curNode.down;
                while (colRemNode != curNode)
                {
                    colRemNode.left.right = colRemNode.right;
                    colRemNode.right.left = colRemNode.left;

                    colRemNode = colRemNode.down;
                }



                if (dancingLinksAlg())
                {
                    return(true);
                }

                #endregion

                #region Readd
                else
                {
                    //If removing this row didn't work, backtrack and undo all those row and column removals.

                    columns.Add(curNode.header);

                    curNode.right.left = curNode;
                    curNode.left.right = curNode;


                    DancingLinksNode colAddNode = curNode.down;
                    while (colAddNode != curNode)
                    {
                        colAddNode.left.right = colAddNode.right;
                        colAddNode.right.left = colAddNode.left;

                        colAddNode = colAddNode.down;
                    }

                    //Now, we follow the links into the inner rows and columns to restore them as well.
                    curColPivot = curNode.right;

                    while (curColPivot != curNode)
                    {
                        DancingLinksNode curRowPivot = curColPivot.down;

                        while (curRowPivot != curColPivot)
                        {
                            #region Add_rows_Except_Pivot_Row
                            DancingLinksNode curAddNode = curRowPivot.right;
                            while (curAddNode != curRowPivot)
                            {
                                curAddNode.up.down = curAddNode;
                                curAddNode.down.up = curAddNode;

                                curAddNode.header.columnMemberCount++;

                                curAddNode = curAddNode.right;
                            }

                            rows.Add(rowLookUp[curRowPivot.row]);
                            #endregion

                            //curRowPivot.right.left = curRowPivot.left;
                            //curRowPivot.left.right = curRowPivot.right;

                            curRowPivot = curRowPivot.down;
                        }

                        columns.Add(curColPivot.header);

                        //We must Add the Pivot Row as well.
                        curColPivot.up.down = curColPivot;
                        curColPivot.down.up = curColPivot;

                        curColPivot = curColPivot.right;
                    }
                }
                #endregion

                curNode = curNode.down;
                count--;
            }

            return(false);
        }