Форум программистов, компьютерный форум CyberForum.ru

Гаусс для коллекции - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 117, средняя оценка - 4.91
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.03.2010, 04:57     Гаусс для коллекции #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
double abs(double x)
{
 if (x<0)
 {
  return -x;
 }
 return x;
}
void Gauss(double *a, double *b, double *&x, unsigned short int n) // а - матрица коэффициентов, строки подряд, b - свободные члены, x - решение.
{
 unsigned hort int i,j,k,t;
 double kof,s;
 if (x) // Если какой-то вектор решений уже дан
 {
  delete [] x; // Сотрём его нафиг!
 }
 for (i=n-1; i>0; --i) // Цикл по уравнениям - вычитаемым
 {
  for (t=i, j=i-1; j>=0; --j) Ищем строку с максимальным в i-том столбце коэффициентом.
  {
   if (abs(a[i+t*n])<abs(a[i+j*n])
   {
    t=j;
   }
  }
  if (a[i+t*n]==0.0)
  {
   return;
  }
  if (t!=i) // Если она не i-тая
  {
   for (k=n-1; k>=0; --k) // Меняем её с i-той
   {
    a[k+t*n]&=a[k+i*n];
    a[k+i*n]&=a[k+t*n];
    a[k+t*n]&=a[k+i*n];
   }
  }
  for (j=i-1; j>=0; --j) // Цикл пл уравнениям-уменьшаемым
  {
   kof=a[i+j*n]/a[i+i*n]; // kof=a[j][i]/a[i][i];
   for (a[i+j*n]=0.0, b[j]-=b[i]*kof, k=i-1; k>=0; --k) // Цикл по столбцам
   {
    a[k+j*n]-=a[k+i*n]*kof; // a[k][j]-=a[k][i]*kof
   }
  }
 }
 x=new double [n];
 if (x)
 {
  for (i=0; i<n; ++i)
  {
   for (s=0.0, j=i-1, j>=0; --j)
   {
    s+=a[j+i*n]*x[j]; //s+=a[j][i]*x[j]
   }
   x[i]=(b[i]-s)/a[i+i*n]; // x[i]=(b[i]-s)/a[i][i];
  }
 }
}
Добавлено через 16 часов 59 минут
Решенная здесь задача.
Дано: матрица a коэффициентов системы уравнений в в виде линерализованного массива (a[0][0], a[1][0], a[2][0]... a[n-1][0], a[0][1], a[1][1], a[2][1]...a[n-1][1], a[0][2], a[1][2], a[2][2]...a[n-1][2]...a[0][n-1], a[1][n-1], a[2][n-1]...a[n-1][n-1]), вектор-столбец b свободных членов той же системы уравнений и число уравнений. Матрица квадратная, число элементов вектора равно числу строк матрицы. Система эквивалентна матричному уравнению a*x=b. Требуется найти: вектор x решений системы уравнений. Если система не имеет однозначного решения, вернуть пустой указатель на массив x.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2010, 04:57     Гаусс для коллекции
Посмотрите здесь:

Крамер для коллекции C++
Гаусс( C++
C++ Гаусс
C++ Гаусс
C++ Гаусс
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vet
 Аватар для vet
175 / 175 / 13
Регистрация: 08.04.2009
Сообщений: 1,309
16.03.2010, 05:15     Гаусс для коллекции #2
Цитата Сообщение от taras atavin Посмотреть сообщение
for (k=n-1; k>=0; --k) // Меняем её с i-той
{
a[k+t*n]&=a[k+i*n];
a[k+i*n]&=a[k+t*n];
a[k+t*n]&=a[k+i*n];
}
taras atavin, а каким компилятором пользуешься?
У меня в этом блоке и Dev-C++ и VS 2008 пишут одно и тоже: что нельзя использовать тип double с операцией поразрядного присваивания &= ...?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.03.2010, 05:56  [ТС]     Гаусс для коллекции #3
Для инта почему-то работало, вот я и заменил. Придётся заменить назад: в оргинале был обмен через temp.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
double abs(double x)
{
 if (x<0)
 {
  return -x;
 }
 return x;
}
void Gauss(double *a, double *b, double *&x, unsigned short int n) // а - матрица коэффициентов, строки подряд, b - свободные члены, x - решение.
{
 unsigned hort int i,j,k,t;
 double kof,s;
 double temp;
 if (x) // Если какой-то вектор решений уже дан
 {
  delete [] x; // Сотрём его нафиг!
 }
 for (i=n-1; i>0; --i) // Цикл по уравнениям - вычитаемым
 {
  for (t=i, j=i-1; j>=0; --j) Ищем строку с максимальным в i-том столбце коэффициентом.
  {
   if (abs(a[i+t*n])<abs(a[i+j*n])
   {
    t=j;
   }
  }
  if (a[i+t*n]==0.0)
  {
   return;
  }
  if (t!=i) // Если она не i-тая
  {
   for (k=n-1; k>=0; --k) // Меняем её с i-той
   {
    temp=a[k+t*n];
    a[k+t*n]=a[k+i*n];
    a[k+i*n]=temp;
   }
  }
  for (j=i-1; j>=0; --j) // Цикл пл уравнениям-уменьшаемым
  {
   kof=a[i+j*n]/a[i+i*n]; // kof=a[j][i]/a[i][i];
   for (a[i+j*n]=0.0, b[j]-=b[i]*kof, k=i-1; k>=0; --k) // Цикл по столбцам
   {
    a[k+j*n]-=a[k+i*n]*kof; // a[k][j]-=a[k][i]*kof
   }
  }
 }
 x=new double [n];
 if (x)
 {
  for (i=0; i<n; ++i)
  {
   for (s=0.0, j=i-1, j>=0; --j)
   {
    s+=a[j+i*n]*x[j]; //s+=a[j][i]*x[j]
   }
   x[i]=(b[i]-s)/a[i+i*n]; // x[i]=(b[i]-s)/a[i][i];
  }
 }
}
vet
 Аватар для vet
175 / 175 / 13
Регистрация: 08.04.2009
Сообщений: 1,309
16.03.2010, 05:58     Гаусс для коллекции #4
Цитата Сообщение от taras atavin Посмотреть сообщение
Для инта почему-то работало, вот я и заменил.
Все верно поразрядные либо с int либо,что чаще, с unsigned int используются
vet
 Аватар для vet
175 / 175 / 13
Регистрация: 08.04.2009
Сообщений: 1,309
22.03.2010, 14:45     Гаусс для коллекции #5
taras atavin, код немного был с помарками и немного глючил =))), я вроде исправил,но щас другая проблема, стал корни считать как - то в разнобой, вот пример(но код оч хороший, нули на глав диаг и те "пережевывает", что не во всех реализациях Гаусса бывает):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <cmath>
#include <ctime>
 
using namespace std;
 
void Gauss(double *a, double *b, double *x,int n) // Г* - Г¬Г*òðèöГ* êîýôôèöèåГ*òîâ, ñòðîêè ïîäðÿä, b - ñâîáîäГ*ûå ÷ëåГ*Г», x - ðåøåГ*ГЁГҐ.
{
 int i,j,k,t;
 double kof,s;
 double temp;
 for (i=n-1; i>0; --i) // Г–ГЁГЄГ« ГЇГ® ГіГ°Г*ГўГ*ГҐГ*ГЁГїГ¬ - âû÷èòГ*åìûì
 {
  for (t=i, j=i-1; j>=0; --j) //Èùåì ñòðîêó Г± Г¬Г*ГЄГ±ГЁГ¬Г*ëüГ*ûì Гў i-òîì ñòîëáöå êîýôôèöèåГ*òîì.
  {
   if (fabs(a[i*n+t])<fabs(a[i*n+j]))
   {
    t=j;
   }
  }
  if (a[i*n+t]==0.0)
  {
   return;
  }
  if (t!=i) // Åñëè Г®Г*Г* Г*ГҐ i-ГІГ*Гї
  {
   for (k=n-1; k>=0; --k) // ГЊГҐГ*ГїГҐГ¬ ГҐВё Г± i-òîé
   {
    temp=a[k*n+t];
    a[k*n+t]=a[k*n+i];
    a[k*n+i]=temp;
   }
  }
  for (j=i-1; j>=0; --j) // Г–ГЁГЄГ« ГЇo ГіГ°Г*ГўГ*ГҐГ*ГЁГїГ¬-óìåГ*ГјГёГ*åìûì
  {
   kof=a[i+j*n]/a[i*n+i]; // kof=a[j][i]/a[i][i];
   for (a[i+j*n]=0.0, b[j]-=b[i]*kof, k=i-1; k>=0; --k) // Г–ГЁГЄГ« ГЇГ® ñòîëáöГ*Г¬
   {
    a[k+j*n]-=a[k+i*n]*kof; // a[k][j]-=a[k][i]*kof
   }
  }
 }
 x=new double [n];
 if (x)
 {
  for (i=0; i<n; ++i)
  {
   for (s=0.0, j=i-1; j>=0; --j)
   {
    s+=a[j+i*n]*x[j]; //s+=a[j][i]*x[j]
   }
   x[i]=(b[i]-s)/a[i*n+i]; // x[i]=(b[i]-s)/a[i][i];
   //cout << x[i] << "\n";
  }
 }
 cout << "\n";
 for (i=0; i<n; ++i)
cout << "x " << x[i] << endl;
}
 
 
main()
{
srand((unsigned)time(NULL));
      int n = 6;
     double gauss2[6] ={1,5,3,7,6,3};
      double M[36]={0, 0, 1,0, 0, 0,0, 0, 0, -1, 0, 0,0, 8, 0, 0, 0, 4,0, 0, 0, 0, 6,0, 0, 6, 0, 0, 0, 0,1, 0, 0, 0, 0, 0 };
        
      double *y = new double[n];
 
    /*  for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
                {
                    //cin >> M[i+j*n];
                     M[i+j*n] = rand()/100;
//cout << "gauss1["<< i << "][" << j << "]=";
//cin >> gauss1[i][j];
                }
        }
*/
for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
                {
                     cout << M[i*n+j] << "  ";
                }
                cout << gauss2[i] << endl;
        }   
      Gauss(M,gauss2,y,n);
       cin.get();
}
Ответ такой: 1, -5, -1.25, 1.17, 1, 3
А должен быть: 3, 1, 1, -5, 1.17, -1.25 (подстановкой в ур-ния проверял)
Весь день седня долбаюсь никак не хочет в нормальном порядке корни искать =(((
Может есть идеи по этому поводу???

Добавлено через 23 часа 56 минут
Может есть мысли по этому поводу???
sergeyq
Сообщений: n/a
26.03.2010, 18:31     Гаусс для коллекции #6
код обратной матрицы бы
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.06.2010, 10:08  [ТС]     Гаусс для коллекции #7
там ещё
Цитата Сообщение от taras atavin Посмотреть сообщение
x[i]=(b[i]-s)/a[i+i*n]; // x[i]=(b[i]-s)/a[i][i];
надо заменить на
C++
1
2
3
4
5
6
7
8
9
10
   if (a[i+i*n]<>0.0)
   {
    x[i]=(b[i]-s)/a[i+i*n]; // x[i]=(b[i]-s)/a[i][i];
   }
   else
   {
    delete [] x; 
    x=NULL;
    return;
   }
vet
 Аватар для vet
175 / 175 / 13
Регистрация: 08.04.2009
Сообщений: 1,309
17.06.2010, 14:55     Гаусс для коллекции #8
Цитата Сообщение от taras atavin Посмотреть сообщение
C++
1
2
3
   if (a[i+i*n]<>0.0)
 
   }
А что такое <> ? в С/С++ нет такого условного оператора
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.06.2010, 11:07  [ТС]     Гаусс для коллекции #9
Цитата Сообщение от vet Посмотреть сообщение
Ответ такой: 1, -5, -1.25, 1.17, 1, 3
А должен быть: 3, 1, 1, -5, 1.17, -1.25 (подстановкой в ур-ния проверял)
Я немножко пропустил, что вместе со строками a должны точно также переставляться и элементы b:
C++
1
2
3
4
5
6
7
8
9
for (k=n-1; k>=0; --k) // Меняем её с i-той
{
 temp=a[k+t*n];
 a[k+t*n]=a[i+t*n];
 a[i+t*n]=temp;
}
temp=b[t];
b[t]=b[i];
b[i]=temp;
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
02.10.2010, 22:23     Гаусс для коллекции #10
Цитата Сообщение от taras atavin Посмотреть сообщение
double abs(double x)
а чем стандартная fabs() не угодила?
Vergil
42 / 36 / 14
Регистрация: 11.11.2009
Сообщений: 238
12.10.2010, 08:27     Гаусс для коллекции #11
Выкладываю свой не консольный вариант, сделанный по алгоритму преподавателя. На особую гениальность не претендует, но работает. Метод Гаусса с выбором наибольшего элемента столбца. Возможно не правильная проверка на линейность. Но у меня приняли. Кажется, здесь есть схожий, а, возможно, и такой же вариант(самый первый пост). Если есть ошибки в программе, прошу мне написать. Сделано на Borland Developer Studio(C++ Builder).
Вложения
Тип файла: rar Гаусс.rar (16.7 Кб, 343 просмотров)
NicholasNoise
Сообщений: n/a
16.10.2010, 23:58     Гаусс для коллекции #12
поделюсь своими трудами...
код "чуть" короче
имеются недоработки (было лень пришивать лишние проверки)
Вложения
Тип файла: txt gauss.txt (2.4 Кб, 472 просмотров)
Крюгер
 Аватар для Крюгер
0 / 60 / 3
Регистрация: 16.11.2012
Сообщений: 409
Записей в блоге: 3
10.11.2013, 09:38     Гаусс для коллекции #13
Цитата Сообщение от vet Посмотреть сообщение
А что такое <> ? в С/С++ нет такого условного оператора
а разве непонятно что в коде это значит что там число отличное от нуля должно быть
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.04.2014, 14:30     Гаусс для коллекции
Еще ссылки по теме:

Классы C++, коллекции и сортировка C++
C++ Линейные коллекции данных
Конструкция языка С++11 цикл по коллекции C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
14.04.2014, 14:30     Гаусс для коллекции #14
Честно говоря офигел... Искал вчера несколько часов решение СЛАУ общего вида. Все либо зависали либо были для частных случаев. В итоге решил довести до ума то, что валялось здесь. Я выяснил (методом внимательного всматривания), что правильным порядок иксов в ответе нарушается из-за изменения порядка строк в A (кстати, так и не понял, почему при этом в b ничего менять не надо и ответ правильный). Быстро дописал костыль, проверил, всё идеально.
Работает, естественно, не слишком быстро но для размерности меньше 1000 сойдёт... Решает меньше секунды...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stack>
void EDM::Gauss(double** A, double *b, double *x, int n)
{
    std::stack<std::pair<size_t,size_t> > swaps;
    int i, j, k, t;
    double kof, s;
    for (i = n - 1; i > 0; --i) {
        for (t=i, j=i-1; j >= 0; --j) {//Поиск максимума в столбце
            if (fabs(A[i][t]) < fabs(A[i][j])) {
                t = j;
            }
        }
        if (A[i][t] == 0.0) {
            return;
        }
        if (t != i) {
            for (k = n - 1; k >= 0; --k) {
                std::swap(A[k][t],A[k][i]);
            }
            swaps.push(std::pair<size_t, size_t>(i,t));
        }
        for (j=i-1; j>=0; --j) {
            kof = A[j][i] / A[i][i];
            A[j][i] = 0.0;
            b[j] -= b[i] * kof;
            for (k = i - 1; k >= 0; --k) {
                A[j][k] -= A[i][k] * kof;
            }
        }
    }
    for (i = 0; i < n; ++i)
    {
        s = 0.0;
        for (j = i - 1; j >= 0; --j) {
            s += A[i][j] * x[j];
        }
        x[i] = (b[i] - s) / A[i][i];
    }
    while (!swaps.empty()) {
        std::swap(x[swaps.top().first], x[swaps.top().second]);
        swaps.pop();
    }
}
Добавлено через 3 минуты
СЛАУ размерностью 5184 решалась 228 секунд... ну да ладно, сойдёт для сельской местности...
Yandex
Объявления
14.04.2014, 14:30     Гаусс для коллекции
Ответ Создать тему
Опции темы

Текущее время: 17:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru