Я пишу функцию для расчета определителя. Матрица - все 4х4 двумерного массива. Я обнаружил, что следующие два кода имеют разные результаты. Я проверяю результат MATLAB.

Я использую тестовый пример, как это

0 2 0 1

3 3 2 1

3 2 4 0

2 2 1 1

Код, который имеет правильный результат:

void determinant()
    {
        double result=1;
        int i;
        int j;
        int k;
        for(i=0;i<4;i++)
        {
            for(j=i+1;j<4;j++)//swap the largest number to diagonal position
            {
                if(matrix[j][i]>matrix[i][i])
                {
                    swap_row(i,j);
                    result=result*(-1);//once swap two rows, result will multiply by (-1)
                }
            }
            for(j=i+1;j<4;j++)
            {
                double divident=matrix[j][i]/matrix[i][i];
                for(k=0;k<4;k++)
                {
                    matrix[j][k]=matrix[j][k]-matrix[i][k]*divident;//here is the different part
                }
            }
        }
        for(i=0;i<4;i++)
        {
            result=result*matrix[i][i];
        }
        cout<<"determinant="<<result<<endl;
    }

Правильный код меняет матрицу в это:

3 3 2 1

0 2 0 1

0 0 2 -0,5

0 0 0 0,25

Однако, как только я пишу этот код без double divident=matrix[j][i]/matrix[i][i];, результат будет поворачивать разные:

void determinant()
    {
        double result=1;
        int i;
        int j;
        int k;
        for(i=0;i<4;i++)
        {
            for(j=i+1;j<4;j++)//swap the largest number to diagonal position
            {
                if(matrix[j][i]>matrix[i][i])
                {
                    swap_row(i,j);
                    result=result*(-1);//once swap two rows, result will multiply by (-1)
                }
            }
            for(j=i+1;j<4;j++)
            {
                for(k=0;k<4;k++)
                {
                    matrix[j][k]=matrix[j][k]-matrix[i][k]*matrix[j][i]/matrix[i][i];//here is the different part
                }
            }
        }
        for(i=0;i<4;i++)
        {
            result=result*matrix[i][i];
        }
        cout<<"determinant="<<result<<endl;
    }

И неправильный код меняет матрицу в это

3 3 2 1

0 2 0 1

0 0 4 0

0 0 0 1

Что касается функции swap_row, это работает так (и я уверен, что проблема здесь не существует):

void swap_elements(double &a, double &b)
{
    double tmp;
    tmp=a;
    a=b;
    b=tmp;
}

void swap_row(int i, int j)
{
    for(column=0;column<4;column++)
    {
        swap_elements(matrix[i][column],matrix[j][column]);
    }
}

Я использую this->display() (функция - это функция пирема в классе) для отслеживания изменений, шаг за шагом, но кажется, что расчет ничего не прав, но заказ отличается (правильный код вычисляется по строке, но неправильно Один рассчитывает по одному элементу в массиве) Что заставляет меня смущать, что я ничего не изменил о цикле. Так в чем разница между этими двумя кодами?

c++
-1
CursorCC 2 Окт 2019 в 07:41

1 ответ

Лучший ответ

Я думаю, что во втором варианте вашего кода вы перезаписываете вещи плохим образом. Рассмотрим петлю над k, предположим i=0 и посмотрите на случай k=0:

matrix[j][0]=matrix[j][0]-matrix[0][0]*matrix[j][0]/matrix[0][0];

Это будет перезаписать запись {matrix[j][0]. Теперь рассмотрим следующую итерацию того же петля, то есть k=1 и еще i=0:

matrix[j][1]=matrix[j][1]-matrix[i][1]*matrix[j][0]/matrix[0][0];

Как видите, это использует элемент matrix[j][0], который вы только что обновили в предыдущей итерации. Так что вы используете новое значение . В правильной версии вашего кода вы вместо этого храните значение matrix[j][0], прежде чем запустить цикл, и, таким образом, используйте правильное необъявленное значение на протяжении всего цикла.

2
Daniel Junglas 2 Окт 2019 в 06:50