/// <summary>
        /// Simulates stage two of the realist network formation simulation.
        /// </summary>
        /// <param name="C">Capability matrix for stage two</param>
        /// <param name="R">Policy relevance matrix (SRG)</param>
        /// <param name="EAF">EAF matrix from stage one</param>
        /// <param name="M">MID matrix</param>
        /// <returns>Expected alliance matrix</returns>
        /// <returns>EA matrix for stage two</returns>
        private static Matrix UpdateSimplifiedRealistStageTwo(Matrix C, Matrix R, Matrix M, Matrix BEA, string outputFile, double br)
        {
            int n = C.Rows;

            Matrix AE = M * BEA;

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (R[i, j] == 1 || AE[i, j] > 0 ) R[i, j] = 1;
                    else R[i, j] = 0;
                }

            R.ZeroDiagonal();
            Matrix SRC = R * C;

            Vector SRGC = new Vector(n);
            for (int i = 0; i < n; ++i)
                SRGC[i] = SRC.GetRowSum(i) * br;

            Matrix EAC = BEA * C;

            Vector AOC = new Vector(n);
            for (int i = 0; i < n; ++i)
            {
                if (EAC.GetRowSum(i) + C[i, i] >= SRGC[i]) AOC[i] = 0;
                else AOC[i] = 1 - ((EAC.GetRowSum(i) + C[i, i]) / SRGC[i]);
            }

            Matrix F = Matrix.Ones(n, n);
            F.ZeroDiagonal();
            Matrix PAN = F - R;
            Matrix PAC = PAN * C;

            Matrix EE = M * M;
            EE.ZeroDiagonal();
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EE[i, j] != 0) EE[i, j] = 1;

            Matrix EEC = EE * C;

            Vector EEM = new Vector(n);

            for (int i = 0; i < n; ++i)
                EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

            Matrix EA = new Matrix(n, n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EAC[i, j] > 0 || AOC[i] <= 0)
                        EA[i, j] = EAC[i, j];
                    else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                        EA[i, j] = EEC[i, j];
                    else
                        EA[i, j] = 0;

            //Copied from Stage 1

            Vector SEA = new Vector(n);

            Matrix previousEA = new Matrix(n);

            Matrix TempEEC = new Matrix(n);

            EEC.CloneTo(TempEEC);

            do
            {

                EA.CloneTo(previousEA);

                for (int i = 0; i < n; ++i)
                    SEA[i] = EA.GetRowSum(i) + C[i, i];

                for (int i = 0; i < n; ++i)
                {
                    if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                    else AOC[i] = 1 - SEA[i] / SRGC[i];
                }

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (EEC[i, j] == EEM[i]) EEC[i, j] = 0;

                for (int i = 0; i < n; ++i)
                    EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                    {
                        if (AOC[i] == 0 || EA[i, j] != 0) ;
                        else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                            EA[i, j] = EEC[i, j];
                        else EA[i, j] = 0;
                    }

                //for (int i = 0; i < n; ++i)
                //    for (int j = 0; j < n; ++j)
                //    {
                //        if (AOC[i] == 0 || EA[i, j] > 0) ;
                //        else if (EEC[i, j] == EEM[i]) EA[i, j] = EEC[i, j];
                //        else EA[i, j] = 0;
                //    }
            } while ((!previousEA.IsSameAs(EA)) && !EEC.IsAllZero && !AOC.IsZeroVector);

            if (!AOC.IsZeroVector)
            {

                //for (int i = 0; i < n; ++i)
                //    for (int j = 0; j < n; ++j)
                //        if (PAC[i, j] > 0 && TempEEC[i, j] != 0) PAC[i, j] = 0;

                //PAC.CopyLabelsFrom(C);
                //MatrixWriter.WriteMatrixToMatrixFile(PAC, outputFile);
                Vector PAM = new Vector(n);

                for (int i = 0; i < n; ++i)
                    PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                            EA[i, j] = PAC[i, j];

                do
                {

                    EA.CloneTo(previousEA);

                    for (int i = 0; i < n; ++i)
                        SEA[i] = EA.GetRowSum(i) + C[i, i];

                    for (int i = 0; i < n; ++i)
                    {
                        if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                        else AOC[i] = 1 - SEA[i] / SRGC[i];
                    }

                    //Matrix output = new Matrix(n, n + 4);
                    //for (int i = 0; i < n; i++)
                    //    for (int j = 0; j < n; j++)
                    //        output[i, j] = EA[i, j];

                    //for (int i = 0; i < n; ++i)
                    //    output[i, n] = SEA[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 1] = SRGC[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 2] = AOC[i];
                    //for (int i = 0; i < n; ++i)
                    //    output[i, n + 3] = 1111;

                    //output.CopyLabelsFrom(C);
                    //MatrixWriter.WriteMatrixToMatrixFile(output, outputFile);

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (PAC[i, j] == PAM[i]) PAC[i, j] = 0;

                    //PAC.CopyLabelsFrom(C);
                    //MatrixWriter.WriteMatrixToMatrixFile(PAC, outputFile);
                    for (int i = 0; i < n; ++i)
                        PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                                EA[i, j] = PAC[i, j];

                } while ((!previousEA.IsSameAs(EA)) && !PAC.IsAllZero && !AOC.IsZeroVector);

            }//if AOC is not all zero

            Matrix EAT = EA.GetTranspose();

            Matrix EAF = new Matrix(n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    EAF[i, j] = EA[i, j] * EAT[i, j];

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (EAF[i, j] != 0) BEA[i, j] = 1;
                    else BEA[i, j] = 0;
                }

            return BEA;
        }
        /// <summary>
        /// Simulates stage one of the SIMPLIFIED realist network formation simulation.
        /// </summary>
        /// <param name="C">Capability matrix</param>
        /// <param name="R">Policy relevance matrix (SRG)</param>
        /// <param name="M">MID matrix</param>
        /// <returns>Expected alliance matrix</returns>
        private static Matrix SimulateSimplifiedRealistStageOne(Matrix C, Matrix R, Matrix M, string outputFile, double br)
        {
            int n = C.Rows;
            Matrix SRC = R * C;
            Vector SRGC = new Vector(n);
            for (int i = 0; i < n; ++i)
                SRGC[i] = SRC.GetRowSum(i) * br;
            Vector AOC = new Vector(n);
            for (int i = 0; i < n; ++i)
            {
                if (SRGC[i] <= C[i, i]) AOC[i] = 0;
                else AOC[i] = 1 - C[i, i] / SRGC[i];
            }

            Matrix F = Matrix.Ones(n, n);
            F.ZeroDiagonal();
            Matrix PAN = F - R;
            Matrix PAC = PAN * C;

            Matrix EE = M * M;
            EE.ZeroDiagonal();
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EE[i, j] != 0) EE[i, j] = 1;

            Matrix EEC = EE * C;
            Vector EEM = new Vector(n);

            for (int i = 0; i < n; ++i)
                EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

            Matrix EA = new Matrix(n, n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (EEC[i, j] == EEM[i] && PAN[i, j] == 1 && AOC[i] != 0)
                        EA[i, j] = EEC[i, j];
                    else
                        EA[i, j] = 0;

            Vector SEA = new Vector(n);

            Matrix previousEA = new Matrix(n);

            do
            {

                EA.CloneTo(previousEA);

                for (int i = 0; i < n; ++i)
                    SEA[i] = EA.GetRowSum(i) + C[i, i];

                for (int i = 0; i < n; ++i)
                {
                    if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                    else AOC[i] = 1 - SEA[i] / SRGC[i];
                }

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (EEC[i, j] == EEM[i]) EEC[i, j] = 0;

                for (int i = 0; i < n; ++i)
                    EEM[i] = Algorithms.MaxValue<double>(EEC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                    {
                        //if (AOC[i] != 0 && EEC[i, j] == EEM[i] && EA[i, j] == 0)
                        //    EA[i, j] = EEC[i, j];

                        if (AOC[i] == 0 || EA[i, j] != 0);
                        else if (PAN[i, j] > 0 && EEC[i, j] == EEM[i])
                            EA[i, j] = EEC[i, j];
                        else EA[i, j] = 0;
                    }

            } while ((!previousEA.IsSameAs(EA)) && !EEC.IsAllZero && !AOC.IsZeroVector);

            if (!AOC.IsZeroVector)
            {

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (PAC[i, j] > 0 && EEC[i, j] != 0) PAC[i, j] = 0;

                Vector PAM = new Vector(n);

                for (int i = 0; i < n; ++i)
                    PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                            EA[i, j] = PAC[i, j];

                EA.CopyLabelsFrom(C);
                do
                {

                    EA.CloneTo(previousEA);

                    for (int i = 0; i < n; ++i)
                        SEA[i] = EA.GetRowSum(i) + C[i, i];

                    for (int i = 0; i < n; ++i)
                    {
                        if (SRGC[i] <= SEA[i]) AOC[i] = 0;
                        else AOC[i] = 1 - SEA[i] / SRGC[i];
                    }

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (PAC[i, j] == PAM[i]) PAC[i, j] = 0;

                    for (int i = 0; i < n; ++i)
                        PAM[i] = Algorithms.MaxValue<double>(PAC.GetRowEnumerator(i));

                    for (int i = 0; i < n; ++i)
                        for (int j = 0; j < n; ++j)
                            if (AOC[i] != 0 && PAC[i, j] == PAM[i] && EA[i, j] == 0)
                                EA[i, j] = PAC[i, j];

                    EA.CopyLabelsFrom(C);
                } while ((!previousEA.IsSameAs(EA)) && !PAC.IsAllZero && !AOC.IsZeroVector);

            }//if AOC is not all zero

            Matrix EAT = EA.GetTranspose();

            Matrix EAF = new Matrix(n);

            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    EAF[i, j] = EA[i, j] * EAT[i, j];

            Matrix BEA = new Matrix(n);
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                {
                    if (EAF[i, j] != 0) BEA[i, j] = 1;
                    else BEA[i, j] = 0;
                }

            return BEA;
        }