Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Изменение двухмерных массивов

Ответить
Настройки темы
C/C++ - Изменение двухмерных массивов

Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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

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

Код: Выделить весь код
	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);

Отправлено: 21:45, 01-07-2008

 

Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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;
}

-------
Ehhh.. what's up, doc?..


Отправлено: 19:03, 02-07-2008 | #2



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

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


С первым вопросом вроде бы разобрался.
Код: Выделить весь код
#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;
}

-------
Ehhh.. what's up, doc?..

Это сообщение посчитали полезным следующие участники:

Отправлено: 19:51, 02-07-2008 | #3


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


Написал нахождение определителя разложением по строке заодно разобрался с двухмерными массивами. Хотя алгоритм очень неэффективный из-за копирования . Можно и без копирования обойтись, но там нужно как-то пересчет индексов для алгебраического дополнения делать, чтобы -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);

}

-------
Ehhh.. what's up, doc?..

Это сообщение посчитали полезным следующие участники:

Отправлено: 21:10, 02-07-2008 | #4


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


Нахождение определителя редукцией.
Количество действий
(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);

}

-------
Ehhh.. what's up, doc?..

Это сообщение посчитали полезным следующие участники:

Отправлено: 23:02, 02-07-2008 | #5


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


Нахождение обратной матрицы
В качестве матрицы взята матрица из №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;
		}
	}
}

-------
Ehhh.. what's up, doc?..


Отправлено: 10:25, 03-07-2008 | #6


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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

Код: Выделить весь код
#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);

}

-------
Ehhh.. what's up, doc?..


Отправлено: 11:21, 03-07-2008 | #7


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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

Код: Выделить весь код
#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;

}

-------
Ehhh.. what's up, doc?..

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:58, 03-07-2008 | #8


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


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

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 15:08, 03-07-2008 | #9


Ветеран


Сообщения: 1404
Благодарности: 135

Профиль | Отправить PM | Цитировать


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

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

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

-------
Ehhh.. what's up, doc?..


Отправлено: 17:16, 03-07-2008 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Изменение двухмерных массивов

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Разное - Обработка массивов данных, программа на паскале. Не могу найти ошибку в программе yulia_hoi Программирование и базы данных 6 08-01-2010 14:50
C/C++ - Обучаемся проектированию двухмерных и трехмерных движков: шаблоны, матрицы и векторы mrcnn Программирование и базы данных 3 10-07-2008 15:55
Разное - Поддержка массивов более 2Тб. neWex Microsoft Windows 2000/XP 0 25-12-2007 14:13
*Решено* | Обработка массивов в С++ Shad0VV Программирование и базы данных 7 15-10-2005 19:59
сравнение двух массивов строк в Си bool Программирование и базы данных 5 04-05-2005 17:04




 
Переход