Exemplo n.º 1
0
 internal MtxOne(Link <MtxOne> prvRow, Link <MtxOne> prvCol, ColHeader header, object rowInfo = null)
 {
     RowLink = new Link <MtxOne>(this, prvRow);
     ColLink = new Link <MtxOne>(this, prvCol);
     Header  = header;
     RowInfo = rowInfo;
 }
Exemplo n.º 2
0
        public IEnumerable <IEnumerable <MtxOne> > Solve()
        {
            // If R[h] == h
            if (_mtx.Solved)
            {
                // print the current solution and return
                yield return(_slnRows);

                yield break;
            }

            // Otherwise choose a column object c
            var       sizeMin   = int.MaxValue;
            ColHeader colSelect = null;

            foreach (var col in _mtx.Columns)
            {
                if (col.Size < sizeMin)
                {
                    if (col.Size == 0)
                    {
                        // Slight shortcut
                        yield break;
                    }

                    colSelect = col;
                    sizeMin   = col.Size;
                }
            }

            // Cover column c
            Debug.Assert(colSelect != null, nameof(colSelect) + " != null");
            colSelect.Cover();

            // For each r <- D[c], D[D[c]],..., while r != c
            foreach (var one in colSelect.Ones)
            {
                // Set O[k] <- r
                _slnRows.Push(one);

                // For each j <- R[r], R[R[r]],..., while j != r
                foreach (var colCovered in one.RowLink.Elements().Skip(1).Select(o => o.Header))
                {
                    // cover column j
                    colCovered.Cover();
                }

                // search(k + 1)
                // NOTE: We don't use k because we put solutions into a stack whose
                // length is kept internal to the stack - effectively, k == _solns.Count.
                foreach (var soln in Solve())
                {
                    yield return(soln);
                }

                // r <- O[k], c <- C[r]
                // NOTE: We haven't altered r (one) or c (colSelect) so no need to reset them here but since we
                // keep our solutions in a stack, we have to pop the current one off
                _slnRows.Pop();

                // For each j <- L[r], L[L[r]],..., while j != r
                foreach (var colUncover in one.RowLink.Elements(false).Skip(1).Select(o => o.Header))
                {
                    colUncover.Uncover();
                }
            }
            // Uncover column c and return
            colSelect.Uncover();
        }