Определитель матрицы NxN

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Определитель матрицы NxN

Re: Определитель матрицы NxN

Romeo » 05 янв 2008, 10:48

Функция getch (сокращение от английского "get char") ждёт до нажатия любой не системной клавиши и как только какая-либо несистемная клавиша нажата возвращает ASCII код этой клавиши. Под системными клавишами в данном случае подразумеваются клавиши CTRL, ALT, SHIFT, PRT SCR, PAUSE, а также toggle клавиши (CAPS LOCK, NUM LOCK, SCROLL LOCK).

В твоей программе результат, возвращаемый функцией getch не анализируется, поэтому еденственная причина, для которой она здесь использована, это добиться приостановки исполнения программы для того, чтобы пользователь смог увидеть результаты её работы.

Re: Определитель матрицы NxN

Z1ppeR » 04 янв 2008, 18:38

Romeo спасибо!! Все работает!! Еще вопрос - в функции main стоит getch()
Я читал про этот оператор, он как-то манипулирует вводом, и с ним используется иногда еще один (не помню какой), но никак не понял как он работает. Зачем он здесь?

Re: Определитель матрицы NxN

Romeo » 04 янв 2008, 16:40

Извиняюсь, там должен стоять rand. Вызов srand тоже нужен, но в самом начале программы для инициализации генератора случайных чисел. Делается это вот так:

Код: Выделить всё

time_t t;
srand((unsigned) time(&t));
Для того, чтобы всё работало нужно не забыть включить соответствующие инклюды:

Код: Выделить всё

#include <stdlib.h>
#include <time.h>

Re: Определитель матрицы NxN

Z1ppeR » 04 янв 2008, 16:33

Исправил как вы написали, но он выдает ошибку "Not an allowed type" в строке
matr[j] = srand() % 100; И еще ругается по поводу пустых скобок srand()
Ох уж эти указатели. . .

Re: Определитель матрицы NxN

Romeo » 04 янв 2008, 14:51

Одно замечание к коду: определитель не будет вычисляться, если порядок матрицы равен 1. Чтобы это исправить, нужно добавить ещё одну проверку в функции determinant на то, что N равно 1 и если это так, возвращать a[0][0].

Re: Определитель матрицы NxN

Romeo » 04 янв 2008, 14:45

Вот, господа, достатоно элегантный алгоритм для вычисления определителя именно тем способом, который предлагал я. Обратите внимание, что при формирование матрицы N-1 степени даже не создаётся полностью новая матрица, а просто используются поинтеры на строки матрицы N порядка. Такой оптимизации можно добиться расклыдывая матрицу по последнему столбцу.

Z1ppeR, чтобы заполнить матрицу случайными числами нужно изменить вот этот код:

Код: Выделить всё

for (i=0;i<=N-1;i++)   {matr[i]=new int[N];} 
На такой код:

Код: Выделить всё

for (i=0;i<=N-1;i++) 
{
   matr[i]=new int[N];
   for (j=0;j<=N-1;j++)
   {
      matr[i][j] = srand() % 100;
   }
} 
В этом случае матрица будет заполнена целыми числами от 0 до 99.

Re: Определитель матрицы NxN

Z1ppeR » 04 янв 2008, 14:23

Привожу код на C++ (не мой=))

Используется рекурсия и динамическое распределение памяти

Код: Выделить всё

#include <iostream.h> 
#include <conio.h> 
#include <math.h> 
 
int** csmatr(int**,int);     // --- Функция создания и вывода матрицы ------- 
double determinant(int**,int);  // --- Функция вычисления определителя --------- 
 
void main(void) 
{ 
  int **a,i,N,**matr; 
// --------------------    Указываем порядок матрицы ------------------------ // 
  clrscr(); 
  cout<<"Введите порядок матрицы: "; cin>>N; 
  cout<<'\n'; 
// -------------------- Создание матрицы и вывод ее на экран ------------- // 
  a=csmatr(matr,N); 
// -------------------- Вывод определителя на экран ---------------------- // 
  cout<<"Определитель матрицы = "<<determinant(a,N); 
// --------------------    Освобождение памяти ------------------------------ // 
  for (i=0;i<=N-1;i++) delete a[i]; 
  delete a; 
 
  getch(); 
} 
 
 
/*--------------------------------------------------------------------------- 
          Функция создания матрицы (обязательно должен быть динамический массив) 
---------------------------------------------------------------------------*/ 
int** csmatr(int **matr,int N) 
{ 
  int i,j; 
 
// --------------------    Формирование строк матрицы ----------------------- // 
  matr=new int*[N]; 
// --------------------    Формирование столбцов матрицы -------------------- // 
  for (i=0;i<=N-1;i++)   {matr[i]=new int[N];} 
 
 return matr; 
 
} 
 
 
/*--------------------------------------------------------------------------- 
            Функция вычисления определителя (должна быть обязательно рекурсия) 
---------------------------------------------------------------------------*/ 
double determinant(int **a, int N) 
{ 
  int i,j; 
  int **matr1; 
/*  int sign=1;*/ 
  double determ=0; 
 
  if (N==2) 
  { 
    determ=a[0][0]*a[1][1]-a[0][1]*a[1][0]; 
  } 
  else 
  { 
    matr1=new int*[N-1]; 
 
    for(i=0;i<N;i++) 
    { 
      for(j=0;j<N-1;j++) 
    { 
      if(j<i)   {matr1[j]=a[j];} 
      else      {matr1[j]=a[j+1];} 
    } 
      determ+=pow(-1,(i+j))*determinant(matr1,N-1)*a[i][N-1]; 
    } 
    delete matr1; 
  } 
 
  return determ; 
  cout<<'\n'; 
} 
Пожалуйста модеры или еще кто-нибудь, вы опытны, расскажите что здесь происходит!! Сам понимаю не до конца. Тут какие-то указатели на указатели. А самое важное то, что нет фактического присвоения значений. Думаю заполнить всю матрицу случайными числами, но как это сделать, что добавить в этот конкретный код?

Re: Определитель матрицы NxN

somewhere » 28 дек 2007, 19:31

&quot писал(а):А вы случаем полную проблему не пробовали решать?
В каком смысле?

Re: Определитель матрицы NxN

jeep » 28 дек 2007, 19:22

somewhere писал(а):Это однозначно, сам замерял - пару лет назад нужно было считать определители матриц 256х256(!), а через перестановки :) это уже не шутка. Можно даже у себя код поискать, но он ассемблере, по теме не подойдет. Число проверок там очень мало, и строчных проходов тоже. Зато потом в итоге, получим определитель матрицы как произведение её диагональных элементов. Ну мне там надо было еще и сам вектор найти, но это уже другая история.
А вы случаем полную проблему не пробовали решать?

Re: Определитель матрицы NxN

jeep » 28 дек 2007, 19:19

Romeo писал(а):Нет, перестановки предложил jeep. Строго по определению определителя (т.е. использую перестановки) однозначно не эффективно. Я предложил разложение по строке. Можно, конечно, и к треугольному виду приводить, но там кучу проверок нужно делать дополнительных. Хотя, опять-таки, не смертельно. Приведение к треугольному, кстати, даже быстрее работать будет.
Если матрицы не большие можно и перестановки. В задаче не указан размер.
Если матрица большая, то можно и схему единственного деления использовать.
При такой схеме число умножений и делений для определителя матрицы порядка n равно (n-1)(n^2+n+3)/3.

Вернуться к началу