Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Изменение двухмерных массивов (http://forum.oszone.net/showthread.php?t=110414)

mrcnn 01-07-2008 21:45 839712

Изменение двухмерных массивов
 
Как сделать так, чтобы была задействована только одна матрица?

Поэлементно что ли копировать? Предположим я поэлементно копирую в матрицу из промежуточного одномерного массива? А потом опять поэлементно заменять содержимое одномерного массива и снова копировать в матрицу?

Код:

        int matrix[X][Y] = {
                {4,-3,-3,4},
                {4,-1,0,5},
                {5,1,5,9}};
        kramer(matrix);

        int matrix1[X][Y] = {
                {3,-5,0,8},
                {3,-5,1,9},
                {-4,1,1,4}};
        kramer(matrix1);

        int matrix2[X][Y] = {
                {-4,2,-5,-11},
                {-1,2,-2,-5},
                {5,4,1,2}};
        kramer(matrix2);

        int matrix3[X][Y] = {
                {-2,3,-5,-20},
                {-5,1,5,-2},
                {-2,3,-3,-16}};
        kramer(matrix3);

        int matrix4[X][Y] = {
                {-2,4,0,-12},
                {2,3,1,0},
                {3,5,-1,-6}};
        kramer(matrix4);

        int matrix5[X][Y] = {
                {5,4,3,8},
                {-4,2,1,-10},
                {2,4,4,4}};
        kramer(matrix5);

        int matrix6[X][Y] = {
                {3,5,3,3},
                {3,5,-5,-21},
                {2,0,1,9}};
        kramer(matrix6);/**/

Я хотел сначала сделать так, но так нельзя
Код:

int matrix[X][Y] = {
                {4,-3,-3,4},
                {4,-1,0,5},
                {5,1,5,9}};
kramer(matrix);

        matrix[X][Y] = {
                {3,-5,0,8},
                {3,-5,1,9},
                {-4,1,1,4}};
        kramer(matrix);


mrcnn 02-07-2008 19:03 840682

1. как объявить указатель на двухмерный массив?

2. как передать двухмерный массив в функцию?

3. как описать функцию, которая получает указатель на двухмерный массив?

Код:

/*
вычеркивание из матрицы d строки и i столбца и
копирование полученной вычеркиванием матрицы в data
*/

#include <stdio.h>

#define X 3

void main()
{
        int matrix[X][X] = {
                {4,-3,-3},
                {4,-1,0},
                {5,1,5}};

        int size=X-1;
        int **data; /*как описать этот указатель правильно*/
        int d=0;
        int i=0;
        int k,l,datai,dataj;
       
        data = new int[size][size];

        datai=0;
        dataj=0;

        for (k=0 ; k<X; k++) //проход про строкам
                {


                        if (k != d){

                                for (l=0; l<X;l++) //проход по столбцам строки
                                {

                                        if (l!=i){

                                                data[datai][dataj]=matrix[k][l];

                                                dataj++;

                                        }

                                }


                                datai++;
                                dataj=0;
                               
                        }
                       


                }

        for (k=0;k<size;k++)
        {
                for(l=0;l<size;l++)
                {
                printf("%d ",data[k][l]);
                }
                printf("\n");
        }

        delete[] data;
}


mrcnn 02-07-2008 19:51 840733

С первым вопросом вроде бы разобрался.
Код:


#include <stdio.h>

#define X 3

void main()
{
        int matrix[X][X] = {
                {4,-3,-3},
                {4,-1,0},
                {5,1,5}};

        int size=X-1;
        int** data; /*как описать этот указатель правильно*/
        int d=0;
        int i=0;
        int k,l,datai,dataj;
       
        data = new int*[size];

        for(k=0;k<size;k++)
        {
                data[k]=new int[size];
        }

        datai=0;
        dataj=0;

        for (k=0 ; k<X; k++) //проход про строкам
                {


                        if (k != d){

                                for (l=0; l<X;l++) //проход по столбцам строки
                                {

                                        if (l!=i){

                                                *((*(data+datai))+dataj)=matrix[k][l];

                                                dataj++;
                                                //printf ("matrix[%d][%d]=%d\n", k,l,matrix[k][l]);

                                        }

                                }


                                datai++;
                                dataj=0;
                               
                        }
                       


                }

        for (k=0;k<size;k++)
        {
                for(l=0;l<size;l++)
                {
                printf("%d ",data[k][l]);
                }
                printf("\n");
        }

        for(k=0;k<size;k++)
        {
                delete[] data[k];
        }

        delete[] data;
}


mrcnn 02-07-2008 21:10 840806

Написал нахождение определителя разложением по строке заодно разобрался с двухмерными массивами. Хотя алгоритм очень неэффективный из-за копирования . Можно и без копирования обойтись, но там нужно как-то пересчет индексов для алгебраического дополнения делать, чтобы -1 возвести в нужную степень.


Код:

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 10

void print_matrix(int **m);
void random_matrix(int **m);
int opredelitel(int **m, int d,int sz);
int poww(int,int);

void main()
{
int mainopr;
        int size=XYZZ;
        int** matrix;
        matrix = new int*[size];

        for(int k=0;k<size;k++)
                {
                matrix[k]=new int[size];
                }

        random_matrix(matrix);
        print_matrix(matrix);
        mainopr=opredelitel(matrix,0,XYZZ);
        printf("%d\n",mainopr);
}

void print_matrix(int **m)
{
int i,j;

for (i=0 ; i<XYZZ; i++)
        {
                for (j=0; j<XYZZ;j++)
                {
                        printf("%d ", m[i][j]);
                }
                printf("\n");
        }

}

void random_matrix(int **m)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<XYZZ; i++)       
        for (j=0; j<XYZZ;j++)               
                m[i][j]=rand()%10;

}


int opredelitel(int **m, int d,int sz)
{
        int** data;
        int result, size,i,k,l,reali,realj,datai,dataj,n,correction,t;
       
        result = 0;

        if ( sz > 2){
                for( i = 0 , reali = d+1 , realj = i+1; i < sz ; i++ , realj=i+1)
                {
                        correction = poww(-1,reali+realj);    // (-1)^(i+j)
                       
                                // копирование матрицы
                                size = sz - 1;

                                data = new int*[size];

                                for(k=0;k<size;k++)
                                {
                                        data[k]=new int[size];
                                }

                                datai=0;
                                dataj=0;

                                for (k=0 ; k<sz; k++) //проход про строкам
                                {
                                        if (k != d){
                                                for (l=0; l<sz;l++) //проход по столбцам строки
                                                {
                                                        if (l!=i){
                                                                data[datai][dataj]=m[k][l];
                                                                dataj++;
                                                        }
                                                }
                                                datai++;
                                                dataj=0;                                               
                                        }
                                }
                                n=opredelitel(data,0,size);
                                t=m[d][i]*correction*n;
                                result+=t;
                        }
                       
                }
        else
                {
                        if (sz==2)
                                {
                                return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
                                }
                        else
                        {
                                if (sz==1)
                                        {
                                        return (m[0][0]);
                                        }                       
                                else
                                        {
                                        printf ("Error");
                                        return (-1);
                                        }
                        }

                }

        return(result);       
}

int poww(int d,int t){
        int st=1;
        int result=1;

        for(st=1; st<=t; st++)
        {
                result*=d;
        }
        return (result);

}


mrcnn 02-07-2008 23:02 840911

Нахождение определителя редукцией.
Количество действий
(n-1)*n+(n-2)*(n-1)+..+3*2+2*1
где n - размерность квадратной матрицы

Код:

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 10

void print_matrix(double **m);
void random_matrix(double **m);
double opredelitel(double **m, int sz);
int poww(int,int);
void change_lines(double **m, int d,int t);

void main()
{
        double mainopr;
        int size=XYZZ;
        double** matrix;
        matrix = new double*[size];

        for(int k=0;k<size;k++)
                {
                matrix[k]=new double[size];
                }       

        random_matrix(matrix);
        print_matrix(matrix);
        mainopr=opredelitel(matrix,XYZZ);
        printf("%f\n",mainopr);
        for(k=0;k<XYZZ;k++)
        {
                delete[] matrix[k];
        }

        delete[] matrix;

}

void print_matrix(double **m)
{
int i,j;

for (i=0 ; i<XYZZ; i++)
        {
                for (j=0; j<XYZZ;j++)
                {
                        printf("%f ", m[i][j]);
                }
                printf("\n");
        }

}

void random_matrix(double **m)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<XYZZ; i++)       
        for (j=0; j<XYZZ;j++)               
                m[i][j]=rand()%10;

}


double opredelitel(double **m, int sz)
{
        double x,result;
        int i,j,k,l,n, num_of_changes;
       
        result = 1;
        num_of_changes=0;

        if ( sz > 2)
                {
                        for(i=0,j=0;i<sz-1;i++,j++)
                                {
                                        if (m[i][j]==0)
                                                {
                                                //ищем строку, где не равны нулю, и переставляем
                                                        for(k=i+1;k<sz;k++)
                                                        {
                                                                if(m[k][j]!=0)
                                                                {
                                                                        change_lines(m,i,k);
                                                                        num_of_changes++;
                                                                        break;
                                                                }
                                                        }
                                                }
                                        //m[i][j] не равен 0
                                        //проход по строке l
                                        for(l=i+1;l<sz;l++)
                                                {                                                       
                                                        if (m[l][j] != 0)
                                                                {
                                                                        //m[0][0]*x+m[1][0]=0 => x=-m[1][0]/m[0][0]
                                                                        //x=-m[1][0]/m[0][0];
                                                                        x=-m[l][j]/m[i][j];
                                                                               
                                                                        //проход по столбцу
                                                                        for (n=j;n<sz;n++)
                                                                        {
                                                                                m[l][n]=m[i][n]*x+m[l][n];                                                                                       
                                                                        }
                                                                }
                                                }
                                }
                }
        else if (sz==2)
                {
                return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
                }
        else if (sz==1)
                {
                return (m[0][0]);
                }                       
        else
                {
                printf ("Error");
                return (-1);
                }

        for(i=0,j=0;i<sz;i++,j++)
        {
                result *= m[i][j] ;
        }
        result *= poww(-1,num_of_changes);
        return(result);       
}

void change_lines(double **m, int d,int t)
{
        int i;
        double temp;
        for (i=0;i< XYZZ;i++)
        {
                temp=m[d][i];
                m[d][i]=m[t][i];
                m[t][i]=temp;
        }
}
int poww(int d,int t){
        int st=1;
        int result=1;

        for(st=1; st<=t; st++)
        {
                result*=d;
        }
        return (result);

}


mrcnn 03-07-2008 10:25 841159

Нахождение обратной матрицы
В качестве матрицы взята матрица из №840 учебника Проскурякова

Код:

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 3

void print_matrix(double **m, int sz);
void random_matrix(double **m, int sz);
double opredelitel(double **m, int sz);
void obratnaya_matrix(double **m, double **newm, double mainopr, int sz);
int poww(int,int);
void change_lines(double **m, int sz, int d,int t);
void copy_matrix(double **m, double **newm, int sz);
void copy_matrix(double **m, double **newm, int sz, int d, int i);

void main()
{
        double mainopr;
        int size=XYZZ;
        double** matrix;
        double** newmatrix;
        matrix = new double*[size];
        newmatrix = new double*[size];

        for(int k=0;k<size;k++)
                {
                matrix[k]=new double[size];
                newmatrix[k]=new double[size];
                }
       
        matrix[0][0]=2;matrix[0][1]=5;matrix[0][2]=7;
        matrix[1][0]=6;matrix[1][1]=3;matrix[1][2]=4;       
        matrix[2][0]=5;matrix[2][1]=-2;matrix[2][2]=-3;/*Учебник Проскурякова №840*/

        //random_matrix(matrix);
        print_matrix(matrix,size);
        mainopr=opredelitel(matrix,size);
        printf("Main determinant: %f\n",mainopr);

        /*Обратная матрица существует, если определитель не равен нулю*/
        if (mainopr !=0)
        {
                obratnaya_matrix(matrix, newmatrix, mainopr, size);
                printf("Obratnaya matritsa: \n");
                print_matrix(newmatrix,size);
        }
        else
        {
                printf("Net obratnoy matricy\n");
        }


        for(k=0;k<size;k++)
        {
                delete[] matrix[k];
                delete[] newmatrix[k];
        }

        delete[] matrix;
        delete[] newmatrix;

       
}

void print_matrix(double **m, int sz)
{
int i,j;

for (i=0 ; i<sz; i++)
        {
                for (j=0; j<sz;j++)
                {
                        printf("%f ", m[i][j]);
                }
                printf("\n");
        }

}

void random_matrix(double **m, int sz)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<sz; i++)       
        for (j=0; j<sz;j++)               
                m[i][j]=rand()%10;

}

void copy_matrix(double **m, double **newm, int sz)
{
        int i,j;
        for (i=0 ; i<sz; i++)       
                for (j=0; j<sz;j++)               
                        newm[i][j]=m[i][j];

}
void copy_matrix(double **m, double **newm, int sz, int d, int i)
{
        int k,l,newmi,newmj;

        newmi=0;
        newmj=0;

        for (k=0 ; k<sz; k++)
                {
                if (k != d)
                        {
                                for (l=0; l<sz;l++)
                                {
                                        if (l!=i)
                                        {
                                                newm[newmi][newmj]=m[k][l];
                                                newmj++;
                                        }
                                }
                                newmi++;
                                newmj=0;                                               
                        }
                }
}

double opredelitel(double **m, int sz)
{
        double x,result;
        int i,j,k,l,n, num_of_changes;
        double** matrix_copy;

        matrix_copy = new double*[sz];
        for(k=0;k<sz;k++)
                matrix_copy[k]=new double[sz];
        copy_matrix(m,matrix_copy,sz);
       
        result = 1;
        num_of_changes=0;

        if ( sz > 2)
                {
                        for(i=0,j=0;i<sz-1;i++,j++)
                                {
                                        if (matrix_copy[i][j]==0)
                                                {                                               
                                                        for(k=i+1;k<sz;k++)
                                                        {
                                                                if(matrix_copy[k][j]!=0)
                                                                {
                                                                        change_lines(matrix_copy,sz,i,k);
                                                                        num_of_changes++;
                                                                        break;
                                                                }
                                                        }
                                                }
                                        for(l=i+1;l<sz;l++)
                                                {                                                       
                                                                if (matrix_copy[l][j] != 0)
                                                                        {
                                                                                x=-matrix_copy[l][j]/matrix_copy[i][j];
                                                                                for (n=j;n<sz;n++)
                                                                                {
                                                                                        matrix_copy[l][n]=matrix_copy[i][n]*x+matrix_copy[l][n];
                                                                                }
                                                                        }
                                                }
                                }
                }
        else if (sz==2)
                {
                return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
                }
        else if (sz==1)
                {
                return (m[0][0]);
                }                       
        else
                {
                printf ("Error");
                return (-1);
                }

        for(i=0,j=0;i<sz;i++,j++)
        {
                result *= matrix_copy[i][j] ;
        }
        result *= poww(-1,num_of_changes);

        for(k=0;k<sz;k++)
                delete[] matrix_copy[k];       
        delete[] matrix_copy;

        return(result);       
}

void change_lines(double **m, int sz, int d,int t)
{
        int i;
        double temp;
        for (i=0;i< sz;i++)
        {
                temp=m[d][i];
                m[d][i]=m[t][i];
                m[t][i]=temp;
        }
}


int poww(int d,int t){
        int st=1;
        int result=1;

        for(st=1; st<=t; st++)
        {
                result*=d;
        }
        return (result);

}



void obratnaya_matrix(double **m, double **newm, double mainopr, int sz)
{       
        /*
        Алгоритм
        1. находим алгебраической дополнение
        2. делим алг. дополнение на определитель
        3. заносим в новую матрицу
        */

        double** data;
        int size, i,j,k,reali,realj,correction;
        double opr, obr_element;

        size = sz - 1;//Размер алгебраического дополнения


        for (i=0;i<sz;i++)
        {
                for( j=0;j<sz;j++)
                {
                        //алгебраическое дополнение
                        data = new double*[size];

                        for(k=0;k<size;k++)
                        {
                                data[k]=new double[size];
                        }
                        // Находим алгебраическое дополнение
                        // Вычеркиваемая строка  i,j
                        copy_matrix(m, data,sz,i,j);

                        //Находим определитель алгебраического дополнения
                        opr=opredelitel(data,size);       

                        reali=i+1;
                        realj=j+1;
                       
                        correction = poww(-1,reali+realj);

                        //Уничтожаем алгебраическое дополнение
                        for(k=0;k<size;k++)
                                {
                                        delete[] data[k];
                                }
                        delete[] data;

                        //Находим обратный элемент
                        obr_element = (opr*correction)/mainopr;

                        //Заносим в обратную матрицу
                        newm[j][i]=obr_element;
                }
        }
}


mrcnn 03-07-2008 11:21 841191

Решение системы линейных уравнений методом Крамера

Код:

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 4

void print_matrix(double **m, int sz);
void print_vector(double *m, int sz);
void random_matrix(double **m, int sz);
void random_vector(double *m, int sz);
double opredelitel(double **m, int sz);
void change_lines(double **m, int sz, int d,int t);
int poww(int,int);
void copy_matrix(double **m, double **newm, int sz);
void change_column_matrix(double **m, double **newm, double *line, int num_column, int sz);
void kramer(double **m, double *line, double mainopr,int sz);

void main()
{
        double mainopr;
        int size=XYZZ;
        double* line;
        double** matrix;
       
        matrix = new double*[size];       

        for(int k=0;k<size;k++)
        {
                matrix[k]=new double[size];               
                }

        line = new double[size];
       


        /* Проскуряков #567*/
        /*matrix[0][0]=3;matrix[0][1]=-2;matrix[0][2]=-5;matrix[0][3]=1;
        matrix[1][0]=2;matrix[1][1]=-3;matrix[1][2]=1;matrix[1][3]=5;       
        matrix[2][0]=1;matrix[2][1]=2;matrix[2][2]=0;matrix[2][3]=-4;
        matrix[3][0]=1;matrix[3][1]=-1;matrix[3][2]=-4;matrix[3][3]=9;
        line[0]=3; line[1]=-3; line[2]=-3;line[3]=22;/**/
        /* Проскуряков #568*/
        /*matrix[0][0]=4;matrix[0][1]=-3;matrix[0][2]=1;matrix[0][3]=5;
        matrix[1][0]=1;matrix[1][1]=-2;matrix[1][2]=-2;matrix[1][3]=-3;       
        matrix[2][0]=3;matrix[2][1]=-1;matrix[2][2]=2;matrix[2][3]=0;
        matrix[3][0]=2;matrix[3][1]=3;matrix[3][2]=2;matrix[3][3]=-8;
        line[0]=7; line[1]=3; line[2]=-1;line[3]=-7;/**/

        random_matrix(matrix,size);
        printf("Matrix:\n");
        print_matrix(matrix,size);
        random_vector(line,size);
        printf("Vector:\n");
        print_vector(line,size);       

        mainopr=opredelitel(matrix,size);
        printf("Main determinant: %f\n",mainopr);


        if (mainopr !=0)
        {
                printf("Reshenie: \n");
                kramer(matrix, line,mainopr, size);
        }
        else
        {
                printf("Systema nekramerovskaya\n");
        }

        for(k=0;k<size;k++)
        {
                delete[] matrix[k];                       
        }

        delete[] matrix;
        delete[] line;       
}


void kramer(double **m, double *line, double mainopr,int sz)
{
        int i;
        double** newmatrix;
        double x;

        newmatrix = new double*[sz];
        for(int k=0;k<sz;k++)
        {
                newmatrix[k]=new double[sz];
        }

        for(i=0; i<sz;i++)
        {
                change_column_matrix(m, newmatrix, line, i, sz);
                x=opredelitel(newmatrix,sz)/mainopr;
                printf("x[%d]=%f\n",i,x);
        }

        for(k=0;k<sz;k++)
        {
                delete[] newmatrix[k];
        }

        delete[] newmatrix;

}

void change_column_matrix(double **m, double **newm, double *line, int num_column, int sz)
{

        int i,j;

        if (num_column <sz){
                for (i=0 ; i<sz; i++)
                {       
                        for (j=0; j<sz;j++)       
                        {       
                                if (j != num_column)
                                {
                                        newm[i][j]=m[i][j];
                                }
                                else
                                {
                                        newm[i][j]=line[i];
                                }

                        }
                }
        }
        else
        {
                printf("Error\n");
        }

}

void print_matrix(double **m, int sz)
{
int i,j;

for (i=0 ; i<sz; i++)
        {
                for (j=0; j<sz;j++)
                {
                        printf("%f ", m[i][j]);
                }
                printf("\n");
        }

}

void print_vector(double *m, int sz)
{
int i;

for (i=0 ; i<sz; i++)
        printf("%f ", m[i]);
printf("\n");

}

void random_matrix(double **m, int sz)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<sz; i++)       
        for (j=0; j<sz;j++)               
                m[i][j]=rand()%10;

}

void random_vector(double *m, int sz)
{
int i;
srand (time(NULL));

for (i=0 ; i<sz; i++)       
                m[i]=rand()%10;

}


void copy_matrix(double **m, double **newm, int sz)
{
        int i,j;
        for (i=0 ; i<sz; i++)       
                for (j=0; j<sz;j++)               
                        newm[i][j]=m[i][j];

}


double opredelitel(double **m, int sz)
{
        double x,result;
        int i,j,k,l,n, num_of_changes;
        double** matrix_copy;

        matrix_copy = new double*[sz];
        for(k=0;k<sz;k++)
                matrix_copy[k]=new double[sz];
        copy_matrix(m,matrix_copy,sz);
       
        result = 1;
        num_of_changes=0;

        if ( sz > 2)
                {
                        for(i=0,j=0;i<sz-1;i++,j++)
                                {
                                        if (matrix_copy[i][j]==0)
                                                {                                               
                                                        for(k=i+1;k<sz;k++)
                                                        {
                                                                if(matrix_copy[k][j]!=0)
                                                                {
                                                                        change_lines(matrix_copy,sz,i,k);
                                                                        num_of_changes++;
                                                                        break;
                                                                }
                                                        }
                                                }
                                        for(l=i+1;l<sz;l++)
                                                {                                                       
                                                                if (matrix_copy[l][j] != 0)
                                                                        {
                                                                                x=-matrix_copy[l][j]/matrix_copy[i][j];
                                                                                for (n=j;n<sz;n++)
                                                                                {
                                                                                        matrix_copy[l][n]=matrix_copy[i][n]*x+matrix_copy[l][n];
                                                                                }
                                                                        }
                                                }
                                }
                }
        else if (sz==2)
                {
                return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
                }
        else if (sz==1)
                {
                return (m[0][0]);
                }                       
        else
                {
                printf ("Error");
                return (-1);
                }

        for(i=0,j=0;i<sz;i++,j++)
        {
                result *= matrix_copy[i][j] ;
        }
        result *= poww(-1,num_of_changes);

        for(k=0;k<sz;k++)
                delete[] matrix_copy[k];       
        delete[] matrix_copy;

        return(result);       
}

void change_lines(double **m, int sz, int d,int t)
{
        int i;
        double temp;
        for (i=0;i< sz;i++)
        {
                temp=m[d][i];
                m[d][i]=m[t][i];
                m[t][i]=temp;
        }
}

int poww(int d,int t){
        int st=1;
        int result=1;

        for(st=1; st<=t; st++)
        {
                result*=d;
        }
        return (result);

}


mrcnn 03-07-2008 11:58 841215

Решение системы линецных уравнений методом обратной матрицы

Код:

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 4

void print_matrix(double **m, int sz);
void print_vector(double *m, int sz);
void random_matrix(double **m, int sz);
void random_vector(double *m, int sz);
double opredelitel(double **m, int sz);
void obratnaya_matrix(double **m, double **newm, double mainopr, int sz);
int poww(int,int);
void change_lines(double **m, int sz, int d,int t);
void copy_matrix(double **m, double **newm, int sz);
void copy_matrix(double **m, double **newm, int sz, int d, int i);
void multiplicate_matrix_and_vector(double **m, double *line, double *result, double mainopr,int sz);

void main()
{
        double mainopr;
        int size=XYZZ;
        double* line;
        double* result;
        double** matrix;
       
        matrix = new double*[size];       

        for(int k=0;k<size;k++)
        {
                matrix[k]=new double[size];               
                }

        line = new double[size];
        result = new double[size];
       
        /* Проскуряков #567*/
        /*matrix[0][0]=3;matrix[0][1]=-2;matrix[0][2]=-5;matrix[0][3]=1;
        matrix[1][0]=2;matrix[1][1]=-3;matrix[1][2]=1;matrix[1][3]=5;       
        matrix[2][0]=1;matrix[2][1]=2;matrix[2][2]=0;matrix[2][3]=-4;
        matrix[3][0]=1;matrix[3][1]=-1;matrix[3][2]=-4;matrix[3][3]=9;
        line[0]=3; line[1]=-3; line[2]=-3;line[3]=22;/**/
        matrix[0][0]=4;matrix[0][1]=-3;matrix[0][2]=1;matrix[0][3]=5;
        matrix[1][0]=1;matrix[1][1]=-2;matrix[1][2]=-2;matrix[1][3]=-3;       
        matrix[2][0]=3;matrix[2][1]=-1;matrix[2][2]=2;matrix[2][3]=0;
        matrix[3][0]=2;matrix[3][1]=3;matrix[3][2]=2;matrix[3][3]=-8;
        line[0]=7; line[1]=3; line[2]=-1;line[3]=-7;

        //random_matrix(matrix,size);
        printf("Matrix:\n");
        print_matrix(matrix,size);
        //random_vector(line,size);
        printf("Vector:\n");
        print_vector(line,size);       

        mainopr=opredelitel(matrix,size);
        printf("Main determinant: %f\n",mainopr);

        if (mainopr !=0)
        {
                printf("Reshenie metodom obratn matricy: \n");
                multiplicate_matrix_and_vector(matrix, line,result, mainopr, size);
        }
        else
        {
                printf("Matritsa ne imeet obratnoy. Metod neprimenim\n");
        }

        for(k=0;k<size;k++)
        {
                delete[] matrix[k];                       
        }

        delete[] matrix;
        delete[] line;
        delete[] result;
}



void print_matrix(double **m, int sz)
{
int i,j;

for (i=0 ; i<sz; i++)
        {
                for (j=0; j<sz;j++)
                {
                        printf("%f ", m[i][j]);
                }
                printf("\n");
        }

}

void print_vector(double *m, int sz)
{
int i;

for (i=0 ; i<sz; i++)
        printf("%f ", m[i]);
printf("\n");

}



void random_matrix(double **m, int sz)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<sz; i++)       
        for (j=0; j<sz;j++)               
                m[i][j]=rand()%10;

}

void random_vector(double *m, int sz)
{
int i;
srand (time(NULL));

for (i=0 ; i<sz; i++)       
                m[i]=rand()%10;

}


void copy_matrix(double **m, double **newm, int sz)
{
        int i,j;
        for (i=0 ; i<sz; i++)       
                for (j=0; j<sz;j++)               
                        newm[i][j]=m[i][j];

}
void copy_matrix(double **m, double **newm, int sz, int d, int i)
{
        int k,l,newmi,newmj;

        newmi=0;
        newmj=0;

        for (k=0 ; k<sz; k++)
                {
                if (k != d)
                        {
                                for (l=0; l<sz;l++)
                                {
                                        if (l!=i)
                                        {
                                                newm[newmi][newmj]=m[k][l];
                                                newmj++;
                                        }
                                }
                                newmi++;
                                newmj=0;                                               
                        }
                }
}


double opredelitel(double **m, int sz)
{
        double x,result;
        int i,j,k,l,n, num_of_changes;
        double** matrix_copy;

        matrix_copy = new double*[sz];
        for(k=0;k<sz;k++)
                matrix_copy[k]=new double[sz];
        copy_matrix(m,matrix_copy,sz);
       
        result = 1;
        num_of_changes=0;

        if ( sz > 2)
                {
                        for(i=0,j=0;i<sz-1;i++,j++)
                                {
                                        if (matrix_copy[i][j]==0)
                                                {                                               
                                                        for(k=i+1;k<sz;k++)
                                                        {
                                                                if(matrix_copy[k][j]!=0)
                                                                {
                                                                        change_lines(matrix_copy,sz,i,k);
                                                                        num_of_changes++;
                                                                        break;
                                                                }
                                                        }
                                                }
                                        for(l=i+1;l<sz;l++)
                                                {                                                       
                                                                if (matrix_copy[l][j] != 0)
                                                                        {
                                                                                x=-matrix_copy[l][j]/matrix_copy[i][j];
                                                                                for (n=j;n<sz;n++)
                                                                                {
                                                                                        matrix_copy[l][n]=matrix_copy[i][n]*x+matrix_copy[l][n];
                                                                                }
                                                                        }
                                                }
                                }
                }
        else if (sz==2)
                {
                return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
                }
        else if (sz==1)
                {
                return (m[0][0]);
                }                       
        else
                {
                printf ("Error");
                return (-1);
                }

        for(i=0,j=0;i<sz;i++,j++)
        {
                result *= matrix_copy[i][j] ;
        }
        result *= poww(-1,num_of_changes);

        for(k=0;k<sz;k++)
                delete[] matrix_copy[k];       
        delete[] matrix_copy;

        return(result);       
}

void change_lines(double **m, int sz, int d,int t)
{
        int i;
        double temp;
        for (i=0;i< sz;i++)
        {
                temp=m[d][i];
                m[d][i]=m[t][i];
                m[t][i]=temp;
        }
}


int poww(int d,int t){
        int st=1;
        int result=1;

        for(st=1; st<=t; st++)
        {
                result*=d;
        }
        return (result);

}



void obratnaya_matrix(double **m, double **newm, double mainopr, int sz)
{       
        /*
        Алгоритм
        1. находим алгебраической дополнение
        2. делим алг. дополнение на определитель
        3. заносим в новую матрицу
        */

        double** data;
        int size, i,j,k,reali,realj,correction;
        double opr, obr_element;

        size = sz - 1;//Размер алгебраического дополнения


        for (i=0;i<sz;i++)
        {
                for( j=0;j<sz;j++)
                {
                        //алгебраическое дополнение
                        data = new double*[size];

                        for(k=0;k<size;k++)
                        {
                                data[k]=new double[size];
                        }
                        // Находим алгебраическое дополнение
                        // Вычеркиваемая строка  i,j
                        copy_matrix(m, data,sz,i,j);

                        //Находим определитель алгебраического дополнения
                        opr=opredelitel(data,size);       

                        reali=i+1;
                        realj=j+1;
                       
                        correction = poww(-1,reali+realj);

                        //Уничтожаем алгебраическое дополнение
                        for(k=0;k<size;k++)
                                {
                                        delete[] data[k];
                                }
                        delete[] data;

                        //Находим обратный элемент
                        obr_element = (opr*correction)/mainopr;

                        //Заносим в обратную матрицу
                        newm[j][i]=obr_element;
                }
        }
}


void multiplicate_matrix_and_vector(double **m, double *line, double *result, double mainopr,int sz)
{
        int i,j;
        double x;
        double** newmatrix;
        newmatrix = new double*[sz];

        for(int k=0;k<sz;k++)
                {
                newmatrix[k]=new double[sz];
                }


        if (mainopr !=0)
        {
                obratnaya_matrix(m, newmatrix, mainopr, sz);
                printf("Obratnaya matritsa: \n");
                print_matrix(newmatrix,sz);

                for (i=0;i<sz;i++)
                {
                        x=0;
                        for (j=0; j<sz;j++)
                        {                               
                                x += newmatrix[i][j]*line[j];
                                                        }
                        result[i]=x;
                        printf("result[%d]=%f\n",i,result[i]);                       
                }
        }
        else
        {
                printf("Error\n");
        }

        for(k=0;k<sz;k++)
        {               
                delete[] newmatrix[k];
        }

        delete[] newmatrix;

}


Drongo 03-07-2008 15:08 841378

mrcnn,
Цитата:

Цитата mrcnn
Решение системы линецных уравнений методом обратной матрицы »

Давно хотел посмотреть на это решение. Спасибо. Вот ещё ссылка на подобный вопрос - Нахождение обратной матрицы, если это конечно, то?

mrcnn 03-07-2008 17:16 841475

Цитата:

Цитата Drongo
Давно хотел посмотреть на это решение. Спасибо. Вот ещё ссылка на подобный вопрос - Нахождение обратной матрицы, если это конечно, то? »

Там по-видимому другой метод используют. Меня учили находить обратную матрицу через алгебраические дополнения. Другие методы я не знаю.

А системы еще можно решить методом блочной матрицы (воздействием на единичную), методом Гаусса. Метод Гаусса решения систем я тоже хочу реализовать, в принципе он простой.

Хочу создать классы для работы с векторами и матрицами, чтобы хорошо разобраться в ООП в С++.


Время: 23:14.

Время: 23:14.
© OSzone.net 2001-