public DancingLinksNode(DancingLinksColumnHeader h, int cellx, int celly, int cellnum) { row = new Triple <int>(cellx, celly, cellnum); header = h; }
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); }