1 Востаннє редагувалося Skyzerks Synx (02.04.2015 16:29:08)

Тема: Метод простої ітерації (помилка в розрахунках) С# console

int N = 10;
            double p = 0.3 * N, t = 0.2 * N;
            int count = 0;
            double[,] A, B;
            A= new double[,]{
                {12.5,1.4,1.1+p,0.7,-7+t}, 
                {1.2,10,1.5,1.7+p,6-0.2*t}, 
                {1.1,2.5-p,11.2,1.3,10.3},
                {0.7,2,3.1,15,-5-t}};
            B = new double[4, 5];
            double[] x, b;
            x = new double[4];
            b = new double[4] { 0, 0, 0, 0 };
            Console.WriteLine("Startup matrix:");
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 5; j++)
                {
                    Console.Write(A[i, j] + "\t");
                    count++;
                    if (count == 4) Console.Write("=");
                    if (count == 5){Console.Write("\n");count = 0;}
                }   //вывести на экран наш массив
            Console.WriteLine();
            double[,] IterationA, IterationB;
            IterationA = new double[4, 5];
            IterationB = new double[4, 5];
            int IterationNum = 0, Iteration = 1;
            double alfa, epsilon =-1;
            double iter, check=0;    //||x(k+1)-x(k)||
            
            Console.WriteLine("Iteration #" + Iteration);
            for (int i = 0; i < 4; i++)  //ищем х1,2,3,4
                for (int j = 0; j < 5; j++)
                {
                    if (Iteration == 1) B[i, j] = A[i, j]; //Первое получение значений массива А
                    if (i == j) B[i, j] = 0;
                    else
                    {
                        if (j < 3) B[i, j] = -B[i, j] / A[i, i];        //x[1..3]=-b[i]/a[i]
                        else B[i, j] = B[i, j] / A[i, i];               //x[4](beta)=b[i]/a[i,i] 
                    }
                    Console.Write(Math.Round(B[i, j], 4) + "\t");
                    count++;
                    if (count == 4) Console.Write("=");
                    if (count == 5) { Console.Write("\n"); count = 0; }
                } //массив B

            for (int i = 0; i < 4; i++) b[i] = B[i, 4];  //beta(1,2,3,4)

            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 5; j++)
                {
                    if (j < 4) x[i] += B[i, j] * b[i];
                    else x[i] += B[i, j];
                } Console.WriteLine(); //значения x

            //alfa (делается 1 раз)
            double[] elem = new double[4]; //значения при х(k)
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                {
                    elem[i] += B[i, j];
                }
            alfa = elem[0];  //||a||
            for (int i = 1; i < 4; i++)
                if (Math.Abs(elem[i]) > alfa) alfa = Math.Abs(elem[i]);
            Console.WriteLine("a=" + alfa);
            //


            if (Iteration%2!=0)
            {
                IterationA = B;
                IterationNum = 1;
            }
            else
            {
                IterationB = B;
                IterationNum = 0;
            }
//первая итерация

            while (check > epsilon)
            {
                epsilon = 0.0001;
                Iteration++;
                if (Iteration>11)
                {
                    Console.WriteLine("TOO MUCH ITERATIONS");
                    break;
                }
                Console.WriteLine("Iteration #" + Iteration);

                for (int i = 0; i < 4; i++)  //ищем х1,2,3,4
                    for (int j = 0; j < 5; j++)
                    {
                        if (Iteration == 1) B[i, j] = A[i, j]; //Первое получение значений массива А
                        if (i == j) B[i, j] = 0;
                        else{
                            if (j < 3) B[i, j] = -B[i, j] / A[i, i];        //x[1..3]=-b[i]/a[i]
                            else B[i, j] = B[i, j] / A[i, i];               //x[4](beta)=b[i]/a[i,i] 
                        }
                        Console.Write(Math.Round(B[i, j], 4) + "\t");
                        count++;
                        if (count == 4) Console.Write("=");
                        if (count == 5){Console.Write("\n"); count = 0;}
                    } //массив B

                for (int i = 0; i < 4; i++) b[i] = B[i, 4];  //beta(1,2,3,4)

                for (int i = 0; i < 4; i++)
                    for (int j = 0; j < 5; j++){
                        if (j < 4) x[i] += B[i, j] * b[i];
                        else x[i] += B[i, j];
                    } Console.WriteLine(); //значения x

                
                if (Iteration%2!=0){
                    IterationA = B;
                    IterationNum = 1;
                }
                else{
                    IterationB = B;
                    IterationNum = 0;
                }
                

                if (Iteration > 1)
                {
                    double[] elem0 = new double[4]; //значения при х(k)
                    double[] elem1 = new double[4]; //значения при х(k+1)
                    for (int i = 0; i < 4; i++)
                        for (int j = 0; j < 4; j++)
                        {
                            elem0[i] += IterationA[i, j];
                            elem1[i] += IterationB[i, j];
                        }
                    for (int i = 0; i < 4; i++)
                        for (int j = 0; j < 5; j++)
                        {
                            Console.Write(IterationA[i, j] + "\t");
                            count++;
                            if (count == 4) Console.Write("=");
                            if (count == 5) { Console.Write("\n"); count = 0; }
                        }   //вывести на экран наш массив IterationA
                    for (int i = 0; i < 4; i++)
                        for (int j = 0; j < 5; j++)
                        {
                            Console.Write(IterationB[i, j] + "\t");
                            count++;
                            if (count == 4) Console.Write("=");
                            if (count == 5) { Console.Write("\n"); count = 0; }
                        }   //вывести на экран наш массив IterationB
                    iter = -10;
                    for (int i = 0; i < 4; i++)
                        if (Math.Abs(elem1[i] - elem0[i]) > iter)
                            iter = Math.Abs(elem1[i] - elem0[i]);
                    //
                    check = iter;
                    Console.WriteLine("alfa = {0},\n||x(k+1)-x(k)|| = {1}", alfa, iter);
                }
                for (int i = 0; i < 4; i++)
                    Console.WriteLine("x[{0}] = {1}", i + 1, x[i]);
                Console.WriteLine();
            }


            Console.ReadKey();

Мій код в принципі працює, але чомусь в циклі while при розгалуженні if на присвоєння некоректно працює. По ідеї коли зайшло в if, в else воно не має зайти. Але в мене воно просто взяло і пройшлось і по if і по else в тому самому циклі (118 рядок). В чім може бути річ?
Хоча, можливо я просто неправильно задав алгоритм.
138-153 рядки для перевірки (можна видалити, якщо мішає)

2

Re: Метод простої ітерації (помилка в розрахунках) С# console

А 71 рядок правильно працює?

3

Re: Метод простої ітерації (помилка в розрахунках) С# console

0xDADA11C7 написав:

А 71 рядок правильно працює?

Працює. Саме тому я не можу зрозуміти чому код косячить.

4

Re: Метод простої ітерації (помилка в розрахунках) С# console

Skyzerks Synx написав:

Мій код в принципі працює, але чомусь в циклі while при розгалуженні if на присвоєння некоректно працює. По ідеї коли зайшло в if, в else воно не має зайти. Але в мене воно просто взяло і пройшлось і по if і по else в тому самому циклі (118 рядок). В чім може бути річ?
Хоча, можливо я просто неправильно задав алгоритм.
138-153 рядки для перевірки (можна видалити, якщо мішає)

Швидше за все, неправильно, бо мені не вдається відтворити заявлену проблему. Якби дійсно спрацьовували обидві гілки - то ми б бачили обидва повідомлення "Гілка A" та "Гілка B".

Подякували: 0xDADA11C71

5 Востаннє редагувалося Skyzerks Synx (03.04.2015 16:05:03)

Re: Метод простої ітерації (помилка в розрахунках) С# console

koala написав:
Skyzerks Synx написав:

Мій код в принципі працює, але чомусь в циклі while при розгалуженні if на присвоєння некоректно працює. По ідеї коли зайшло в if, в else воно не має зайти. Але в мене воно просто взяло і пройшлось і по if і по else в тому самому циклі (118 рядок). В чім може бути річ?
Хоча, можливо я просто неправильно задав алгоритм.
138-153 рядки для перевірки (можна видалити, якщо мішає)

Швидше за все, неправильно, бо мені не вдається відтворити заявлену проблему. Якби дійсно спрацьовували обидві гілки - то ми б бачили обидва повідомлення "Гілка A" та "Гілка B".

Ой, затупив...я забув що в мене в циклі тільки дві точки зупинки. І через це буде просто так виглядати що воно зайшло в одному циклі по черзі в обидва розгалуження.

"P.S"

Вибачаюсь, звісно, за те що не зразу зрозумів чому так, але дякую за зауваження. Через недосипання всяке може почудитись.