示例#1
0
 private void StartSolving()
 {
     _solution          = _lightsOutVars.GetSolution();
     _estimatedState    = new Uinf(_lightsOutVars.B);
     _solving           = true;
     _solverSquareIndex = 0;
     _waitForNext.StartTimer();
 }
 public Uinf(Uinf number)
 {
     _chain = new ulong[number._chain.Length];
     for (int i = _chain.Length - 1; i >= 0; --i)
     {
         _chain[i] = number._chain[i];
     }
     Length = number.Length;
 }
    public static LinkedList <Uinf> RearrangeRowsFromTriangulation(this LinkedList <Uinf> Rows, LinkedList <int> RowsRearrangement, int i) //this returns the original Rows just rearranged, not triangulated
    {
        int ilen     = Rows.Count;
        int zeroRows = 0;
        LinkedListNode <Uinf> NodeRow          = Rows.GetNodeAt(i);
        LinkedList <Uinf>     UnchangedRows    = new LinkedList <Uinf>(Rows);
        LinkedListNode <Uinf> UnchangedNodeRow = UnchangedRows.GetNodeAt(i);

        RowsRearrangement.Clear();
        LinkedListNode <int> NodeRowint = null;

        for (int ii = 0; ii < ilen; ii++)
        {
            RowsRearrangement.AddLast(ii);
            if (ii == i)
            {
                NodeRowint = RowsRearrangement.Last;
            }
        }
        for (Uinf shifted = new Uinf(1ul, ilen) << i; NodeRow != null;)
        {
            if ((NodeRow.Value & shifted) == 0ul)
            {
                NodeRow          = Rows.PushToLast(NodeRow);
                UnchangedNodeRow = UnchangedRows.PushToLast(UnchangedNodeRow);
                NodeRowint       = RowsRearrangement.PushToLast(NodeRowint);
                zeroRows++;
                if (zeroRows == ilen - i)
                {
                    RowsRearrangement.AddFirst(i);
                    return(UnchangedRows);
                }
                continue;
            }
            zeroRows = 0;
            for (LinkedListNode <Uinf> NodeRow2 = NodeRow.Next; NodeRow2 != null; NodeRow2 = NodeRow2.Next)
            {
                if ((NodeRow2.Value & shifted) != 0)
                {
                    NodeRow2.Value ^= NodeRow.Value;
                }
                //Debug.Log(NodeRow2.Value);
            }
            NodeRow          = NodeRow.Next;
            UnchangedNodeRow = UnchangedNodeRow.Next;
            NodeRowint       = NodeRowint.Next;
            shifted        <<= 1;
            i++;
        }
        RowsRearrangement.AddFirst(ilen);
        return(UnchangedRows);
    }
    public static LinkedList <Uinf> TriangulateGauss(this LinkedList <Uinf> Rows, LinkedList <int> RowsRearrangement)
    {
        int ilen = Rows.Count;
        int i;
        int zeroRows = 0;
        LinkedListNode <Uinf> NodeRow = Rows.First;

        for (i = 0, RowsRearrangement.Clear(); i < ilen; i++)
        {
            RowsRearrangement.AddLast(i);
        }
        LinkedListNode <int> NodeRowint = RowsRearrangement.First;

        i = 0;
        for (Uinf shifted = new Uinf(1ul, ilen); NodeRow != null;)
        {
            if ((NodeRow.Value & shifted) == 0ul)
            {
                NodeRow    = Rows.PushToLast(NodeRow);
                NodeRowint = RowsRearrangement.PushToLast(NodeRowint);
                zeroRows++;
                if (zeroRows == ilen - i)
                {
                    RowsRearrangement.AddFirst(i + 1);
                    return(Rows);
                }
                continue;
            }
            zeroRows = 0;
            for (LinkedListNode <Uinf> NodeRow2 = NodeRow.Next; NodeRow2 != null; NodeRow2 = NodeRow2.Next)
            {
                if ((NodeRow2.Value & shifted) != 0)
                {
                    NodeRow2.Value ^= NodeRow.Value;
                }
            }
            NodeRow    = NodeRow.Next;
            NodeRowint = NodeRowint.Next;
            shifted  <<= 1;
            i++;
        }
        RowsRearrangement.AddFirst(ilen);
        return(Rows);
    }
    public static LinkedList <Uinf> TriangulateGauss(this LinkedList <Uinf> Rows, LinkedList <int> RowsRearrangement, MyLib.MyArrayList <Uinf> RowsTransposedAndGaussInfo)
    {
        int ilen = Rows.Count;

        if (RowsRearrangement.Count < ilen)
        {
            return(Rows.RearrangeRowsFromTriangulation(RowsRearrangement, 0).TriangulateGauss(RowsRearrangement, RowsTransposedAndGaussInfo));
        }
        LinkedListNode <Uinf> NodeRow = Rows.First;

        RowsTransposedAndGaussInfo.Clear(Rows.First.Value.Length);
        int i = 0;

        for (Uinf shifted = new Uinf(1ul, ilen); i < RowsRearrangement.First.Value; NodeRow = NodeRow.Next, shifted <<= 1, i++)
        {
            if ((NodeRow.Value & shifted) == 0ul)
            {
                return(Rows.RearrangeRowsFromTriangulation(RowsRearrangement, i).TriangulateGauss(RowsRearrangement, RowsTransposedAndGaussInfo));
            }
            RowsTransposedAndGaussInfo.Add(new Uinf(ilen));
            //Debug.Log(NodeRow.Value);
            int j = 0;

            for (LinkedListNode <Uinf> NodeRow2 = Rows.First; j < i; NodeRow2 = NodeRow2.Next, j++)
            {
                if ((NodeRow2.Value & shifted) != 0ul)
                {
                    RowsTransposedAndGaussInfo.LastElement.SetBit(j);
                }
            }
            j++;
            for (LinkedListNode <Uinf> NodeRow2 = NodeRow.Next; NodeRow2 != null; NodeRow2 = NodeRow2.Next, j++)
            {
                if ((NodeRow2.Value & shifted) != 0ul)
                {
                    NodeRow2.Value ^= NodeRow.Value;
                    RowsTransposedAndGaussInfo.LastElement.SetBit(j);
                    //Debug.Log((i - 1).ToString() + " " + RowsTransposedAndGaussInfo.LastElement.ToString());
                }
            }
        }
        return(Rows);
    }
    public static Uinf operator <<(Uinf num, int times)
    {
        Uinf newnum = new Uinf(num);

        if (times == 0)
        {
            return(newnum);
        }
        ulong[] chain = newnum._chain;
        if (times < _ULONG_BIT_SIZE)
        {
            chain[chain.Length - 1] = (chain[chain.Length - 1] << times) & newnum.MaskOfLastulong;
            for (int i = chain.Length - 2; i >= 0; --i)
            {
                chain[i + 1] |= chain[i] >> (_ULONG_BIT_SIZE - times);
                chain[i]    <<= times;
            }
            return(newnum);
        }
        else
        {       // shift operator autmatically does modulo operation with times
            chain[chain.Length - 1] = (chain[chain.Length - 1] << times) & newnum.MaskOfLastulong;
            int i = chain.Length - 2;
            for (; i >= 0; --i)
            {
                chain[i + 1] |= chain[i] >> (_ULONG_BIT_SIZE - (times & _ULONG_BIT_SIZE_MODULO));
                chain[i]    <<= times;
            }
            i = chain.Length - 1;
            for (int arrayshift = times / _ULONG_BIT_SIZE; i >= arrayshift; --i)
            {
                chain[i] = chain[i - arrayshift];
            }
            for (; i >= 0; --i)
            {
                chain[i] = ALL_ZEROS;
            }
            return(newnum);
        }
    }
    public static Uinf operator >>(Uinf num, int times)
    {
        Uinf newnum = new Uinf(num);

        if (times == 0)
        {
            return(newnum);
        }
        ulong[] chain = newnum._chain;
        if (times < _ULONG_BIT_SIZE)
        {
            chain[0] >>= times;
            for (int i = 1; i < chain.Length; ++i)
            {
                chain[i - 1] |= chain[i] << (_ULONG_BIT_SIZE - times);
                chain[i]    >>= times;
            }
            return(newnum);
        }
        else
        {
            chain[0] >>= times; // shift operator autmatically does modulo operation with times
            int i = 1;
            for (; i < chain.Length; ++i)
            {
                chain[i - 1] |= chain[i] << (_ULONG_BIT_SIZE - (times & _ULONG_BIT_SIZE_MODULO));
                chain[i]    >>= times;
            }
            i = 0;
            for (int arrayshift = times / _ULONG_BIT_SIZE; i < chain.Length - arrayshift; ++i)
            {
                chain[i] = chain[i + arrayshift];
            }
            for (; i < chain.Length; ++i)
            {
                chain[i] = ALL_ZEROS;
            }
            return(newnum);
        }
    }
示例#8
0
 private void ResetVisitedNodes()
 {
     _visitedNodesFlags = new Uinf(Size + _removedNodes);
 }
    public static bool[] SolveForAxeqbFastUINF(bool[,] A, bool[] B)
    {
        int ilen = A.GetLength(0), jlen = A.GetLength(1) + 1;
        LinkedList <Uinf> Rows        = new LinkedList <Uinf>();
        int i;

        for (i = 0; i < ilen; i++)
        {
            Uinf Row  = new Uinf(jlen);
            Uinf temp = new Uinf(1ul, jlen);
            for (int j = 0; j < jlen - 1; j++, temp <<= 1)
            {
                if (A[i, j])
                {
                    Row ^= temp;
                }
            }
            if (B[i])
            {
                Row ^= temp;
            }
            Rows.AddLast(Row);
        }
        i = 0;
        Uinf onezeros                 = new Uinf(1ul, jlen) << ilen;
        int  zeroRows                 = 0;
        LinkedListNode <Uinf> NodeRow = Rows.First;

        for (Uinf shifted = new Uinf(1ul, jlen); NodeRow != null;)
        {
            if (NodeRow.Value == onezeros)
            {
                return(null);
            }
            if ((NodeRow.Value & shifted) == 0)
            {
                LinkedListNode <Uinf> temp = NodeRow;
                NodeRow = NodeRow.Next;
                Rows.Remove(temp);
                Rows.AddLast(temp);
                zeroRows++;
                if (zeroRows == ilen - i)
                {
                    break;
                }
                continue;
            }
            zeroRows = 0;
            for (LinkedListNode <Uinf> NodeRow2 = NodeRow.Next; NodeRow2 != null; NodeRow2 = NodeRow2.Next)
            {
                if ((NodeRow2.Value & shifted) != 0ul)
                {
                    NodeRow2.Value ^= NodeRow.Value;
                }
            }
            NodeRow   = NodeRow.Next;
            shifted <<= 1;
            i++;
        }
        bool[] x = new bool[ilen];
        if (NodeRow == null)
        {
            NodeRow = Rows.Last;
        }
        else
        {
            NodeRow = NodeRow.Previous;
        }
        for (int jstart = --i; NodeRow != null; NodeRow = NodeRow.Previous, i--)
        {
            Uinf Row  = NodeRow.Value;
            bool b    = (Row & onezeros) != 0;
            Uinf temp = new Uinf(1ul, jlen) << jstart;
            for (int j = jstart; j > i; j--)
            {
                b     ^= ((Row & temp) != 0ul) && x[j];
                temp >>= 1;
            }
            x[i] = b;
        }
        return(x);
    }