Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
1

Создать СЛАУ размерности 1000х1000, чтобы система имела только одно решение

02.04.2016, 12:26. Показов 2381. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, как можно создать СЛАУ большой размерности в виде матрицы в c++, чтобы система имела только одно решение?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.04.2016, 12:26
Ответы с готовыми решениями:

Подберите значение параметра a таким образом, чтобы система имела единственное решение
\begin{cases} & \text{ 2x + 3y } = 7 \\ & \text{ 3x + ay } = 3 \\ & \text{ 8x + 18y } = 10...

Решение СЛАУ большой размерности методом сопряженных градиентов
Всем првиет! Возникла проблемка с методом сопряженных градиентов. Если задавать самому значения...

Укажите такое значение параметра, чтобы система уравнений имела бесконечное число решений
Задача такова: Укажите такое число a, чтобы система уравнений \begin{cases}\left|x \right| +...

Решение неопределенных СЛАУ. Странная система
Столкнулся с такой неопределенной СЛАУ 2x1 + 4x2 - 4x3 = 2 -x1 -2x2 +2x3 = -1 Нужно найти...

23
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.04.2016, 18:10 2
Можно плясать от печки. Создать единичную матрицу, затем применить серию преобразований, включающих умножение строки на случайный ненулевой коэффициент и сложение с другой случайно выбранной строкой.
1
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:14  [ТС] 3
Nick Alte, можете подсказать как?
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.04.2016, 18:16 4
Цитата Сообщение от nokiago Посмотреть сообщение
можете подсказать как?
Надо разъяснить, что такое умножение строки матрицы на число? Или как складывать одну строку с другой?
0
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:23  [ТС] 5
Nick Alte, нет, я не понимаю, как из того, что вы сказали, сделать нужную матрицу
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.04.2016, 18:42 6
Цитата Сообщение от nokiago Посмотреть сообщение
нет, я не понимаю, как из того, что вы сказали, сделать нужную матрицу
Попробую выразиться попроще.
Сначала берём единичную матрицу (ту, в которой везде нули, а на главной диагонали - единицы). У неё заведомо есть ровно одно решение.
Начинаем наугад брать разные строки, умножать их на случайно выбранные (но ненулевые) числа и складывать с другими наугад выбранными строками. Каждое такое преобразование не "испортит" матрицу в том смысле, что у неё останется единственное решение.
Делаем много-много таких преобразований. Десятки тысяч. Сколько терпения хватит. Теперь матрица набита огромным количеством разнообразных случайных чисел во всех местах, но у неё по-прежнему ровно одно решение.
1
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:52  [ТС] 7
Nick Alte, вот сейчас вроде бы всё полностью понял, спасибо большое. А на практике только не знаю, как складывать с рандомными строками. Единичную матрицу сделаю, строки умножу через rand, при этом исключив нули. А вот как сложить с рандомной строкой рандомную строку?
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.04.2016, 18:57 8
Цитата Сообщение от nokiago Посмотреть сообщение
А вот как сложить с рандомной строкой рандомную строку?
Очень просто. Выбираем случайное число от 0 до 999, это номер исходной строки. Назовём его N1. Строка с этим номером - обычный массив из 1000 чисел. Находим другое число, тоже от 0 до 999, называем N2. Смотрим, чтобы N1 не был равен N2. Выбираем случайный ненулевой коэффициент K. Затем к каждому элементу строки N2 добавляем соответствующий элемент строки N1, умноженный на K:
C++
1
2
for(int i = 0; i < 1000; ++i)
    matrix[N2][i] += matrix[N1][i] * K;
1
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 19:04  [ТС] 9
Nick Alte, Спасибо! попробую это сделать на практике
0
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
04.04.2016, 16:23  [ТС] 10
Nick Alte, у меня получилось создать единичную матрицу, матрицу свободных членов и через большое количество итераций заполнить матрицу, которая имеет только одно решение.
я создал матрицу 1000х1000 и вектор B в 1000 элементов, который равен [1,2,...,1000]. Соответственно, у меня есть сейчас найденные x1,...,x1000. (x1 = 1, x2 = 2, x1000 = 1000).
Я правильно мыслю, что по преобразованию строк в матрице 1000х1000 и той же строки в векторе B, решения (x1=1,x2=2,...,x1000=1000), если я захочу решить эту матрицу, мои искомые x1,...,x1000 останутся прежними?

и ещё один вопрос, можно ли как-то сделать так, чтобы коэффициенты в матрице и в векторе были не такими огромными или не такими маленькими (потому что записываются числа у меня с е+006 или е-007 и т.д.).
привожу код, где создается и записывается эта матрица и вектор

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
// matrica.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include<time.h>
#include<stdlib.h>
#include <fstream>
 
#define n 1000
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    srand(time(NULL));
    double tab[n][n];
    
    double B[n];
    for(int i=0;i<n;i++) {
        B[i]=i+1;
    }
    
 
    int i=0, j=0;
 
    for (i=0; i<n; i++)
    {
        for (j=0; j<n; j++) {
            if (i==j) 
            {tab[i][j]=1;}               
            else 
            {tab[i][j]=0;}
        }
    }
 
        double K;
        int N2,N1;
 
        for(int i=0;i<10000;i++) {
        K=(0.1+rand()%1);
        N1=rand()%n;
        N2=rand()%n;
 
        for(int ii = 0; ii < n; ++ii)
        {
            if(N1 != N2) {
                tab[N2][ii] += tab[N1][ii] * K;
                if(ii==0) {B[N2] = B[N2] + B[N1]*K;}
            }
        }
        }
 
        ofstream f;
 
        for(int i=0;i<n;i++) {
        f.open("e:\\b_matrix.txt", ios_base::app);
        f<<B[i]<<" ";
        f.close();
        }
 
 
        for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            f.open("e:\\matrix.txt", ios_base::app);
            f<<tab[i][j]<<" ";
            f.close();
        }
            f.open("e:\\matrix.txt", ios_base::app);
            f<<"\n";
            f.close();
    }
 
    system("pause");
    return 0;
}
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
04.04.2016, 20:00 11
Цитата Сообщение от nokiago Посмотреть сообщение
Я правильно мыслю,
Не совсем правильно, если не по сути, то в формулировке. Матрица - это преобразование, которое из любого набора входных чисел A делает некий выходной набор чисел B. Единичная матрица, с которой начинается процесс, выдаёт на выходе то же, что получает на входе.
"Решением" матрицы является обратная матрица, которой на вход можно подать B и получить в результате A.
После описанных мной умножений-сложений матрица будет содержать некоторое произвольное линейное преобразование. Её можно будет решить и получить обратную матрицу.
То, что сейчас в программе делается с массивом B - отслеживаются вносимые в матрицу преобразования и воспроизводятся. То есть, это некий способ вручную воспроизвести умножение исходного вектора на полученную матрицу.

Цитата Сообщение от nokiago Посмотреть сообщение
и ещё один вопрос, можно ли как-то сделать так, чтобы коэффициенты в матрице и в векторе были не такими огромными
Для начала надо правильно вычислять коэффициент K. Сейчас он всегда равен 0.1: не забываем, что функция rand() возвращает целые числа, и операция % тоже целочисленная. Если позволить ему принимать отрицательные значения (например, в диапазоне -1;1, или -2;2, или даже -5;5), то итоговые коэффициенты в матрице окажутся более-менее сбалансированными.
0
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
04.04.2016, 22:41  [ТС] 12
Nick Alte,
вот я сейчас изменил коэффициенты стали лучше намного, но почему они все целочисленные получаются?
а вектор B я сделал рандомным
Кликните здесь для просмотра всего текста
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
// matrica.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include<time.h>
#include<stdlib.h>
#include <fstream>
 
#define n 1000
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
 
 
    srand(time(NULL));
    double tab[n][n];
 
    /* */
    double B[n];
    for(int i=0;i<n;i++) {
        B[i]=rand()%10;
    }
 
    ofstream f1;
 
        for(int i=0;i<n;i++) {
        f1.open("e:\\b_matrix_old.txt", ios_base::app);
        f1<<B[i]<<" ";
        f1.close();
        }
 
    /* */
 
    int i=0, j=0;
 
    for (i=0; i<n; i++)
    {
        for (j=0; j<n; j++) {
            if (i==j) 
            {tab[i][j]=1;}               
            else 
            {tab[i][j]=0;}
        }
    }
 
 
        double K;
        int N2,N1;
        
        for(int i=0;i<10000;i++) {
        K=(1+rand()%1);
        N1=rand()%n;
        N2=rand()%n;
 
        for(int ii = 0; ii < n; ++ii)
        {
            if(N1 != N2) {
                tab[N2][ii] += tab[N1][ii] * K;
                if(ii==0) {B[N2] = B[N2] + B[N1]*K;}
            }
        }
        }
 
 
        ofstream f;
 
        for(int i=0;i<n;i++) {
        f.open("e:\\b_matrix.txt", ios_base::app);
        f<<B[i]<<" ";
        f.close();
        }
 
 
        for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            f.open("e:\\matrix.txt", ios_base::app);
            f<<tab[i][j]<<" ";
            f.close();
        }
            f.open("e:\\matrix.txt", ios_base::app);
            f<<"\n";
            f.close();
    }
 
    system("pause");
    return 0;
}


я просто двигаюсь от того, что мне нужно решить матрицу 1000х1000.
решаю я через специальные библиотеки с++, которые служат для вычислений линейной алгебры.
но я ведь должен знать ответы, чтобы видеть - правильно ли решают эти библиотеки.
как вы сказали создать единичную матрицу - для меня это хороший вариант, так как я задаю как бы последний столбец (вектор б) - он и будет моим решением, я получается буду знать ответы.

вот смотрите, я сейчас полуил матрицу заполненную и вектор тот тоже модифицированный, потом я эти данные ввожу уже в программу для вычисления - и программа мне находит решения в виде того "старого" вектора, который был при матрице единичной. правильно ли это или я запутался?

спасибо за ответы, реально помогаете.
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
04.04.2016, 22:57 13
Цитата Сообщение от nokiago Посмотреть сообщение
но почему они все целочисленные получаются?
Потому что вырастают из целочисленных операций. Так, остаток от деления любого числа на 1 - ноль. А ведь именно это и означает rand()%1.
К примеру, если мы хотим получать число в диапазоне от -5 до 5 с шагом 0.001, надо написать:
Код
K = ((rand() % 10001) - 5000) / 1000.0;
Выражение в скобках даст нам целое число от -5000 до 5000, а деление на вещественную константу даст вещественный результат. Конечно, надо будет проверить, чтобы он был ненулевой.

Цитата Сообщение от nokiago Посмотреть сообщение
программа мне находит решения в виде того "старого" вектора, который был при матрице единичной
Да. Но можно попросту умножать исходный вектор на уже полученную матрицу, заодно программа станет менее запутанной.
0
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
04.04.2016, 23:08  [ТС] 14
Nick Alte,
Да. Но можно попросту умножать исходный вектор на уже полученную матрицу, заодно программа станет менее запутанной.
Да, но предполагается, что решений у меня нет, это я так, только для проверки.

не по теме:
а вообще, какие способы лучше использовать для решения такой обычной матрицы?
я использовал гаусса, lu, обратной матрицы (при помощи библиотек с++ (armadillo, blas/lapack))
я так понял, что методом Крамера это нет смысла решать? (большое количество вычислений)

хотел бы ещё итерационными методами попробовать решить, но насколько я знаю, должно выполняться условие сходимости. Если знаете, можете объяснить что к чему?
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
04.04.2016, 23:16 15
Цитата Сообщение от nokiago Посмотреть сообщение
Да, но предполагается, что решений у меня нет, это я так, только для проверки.
Итог всё равно тот же самый, просто получение проверочных значений будет отделено от создания матрицы, что есть хорошо.

Цитата Сообщение от nokiago Посмотреть сообщение
а вообще, какие способы лучше использовать для решения такой обычной матрицы?
Учитывая способ её получения, у неё не будет каких-то специальных свойств, так что обычные универсальные методы, начиная с того же Гаусса, будут наиболее уместны.

Цитата Сообщение от nokiago Посмотреть сообщение
но насколько я знаю, должно выполняться условие сходимости.
Тут надо в матан залезать, но вроде бы на такой матрице должно хорошо сходиться, там нет дикого разброса коэффициентов и прочих неприятных вещей.
1
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
04.04.2016, 23:21  [ТС] 16
Учитывая способ её получения, у неё не будет каких-то специальных свойств, так что обычные универсальные методы, начиная с того же Гаусса, будут наиболее уместны.
то есть Гаусс, LU - а какие ещё можно использовать для обычных таких матриц?
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
05.04.2016, 18:46 17
Любые, не предназначенные для решения матриц специального вида. Впрочем, какого-то существенного выигрыша по сравнению с обычным Гауссом ждать не приходится.
1
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
09.04.2016, 15:06  [ТС] 18
Nick Alte, скажите пожалуйста, а в теории как можно сделать матрицу, такую как вы и писали выше, только чтобы диагональные элементы по модулю были самые большие? можно это как то сделать через единичную матрицу?
0
28 / 20 / 97
Регистрация: 22.10.2015
Сообщений: 304
09.04.2016, 15:09 19
nokiago, можно
0
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
09.04.2016, 15:22  [ТС] 20
dcshowcousa, можно ли так:
у меня есть единичная матрица - я сначала домножу каждую строку, допустим на 10, тогда у меня вместо 1 в матрице будут десятки, а потом буду прибавлять к рандомной строке рандомную строку, умноженную на ненулевой коэффициент в диапазоне меньшим чем 10?
0
09.04.2016, 15:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.04.2016, 15:22
Помогаю со студенческими работами здесь

Решение СЛАУ система решений алгебраических уравненийметодм гаусса
Program Gauss; uses crt; const e=0.000001; const f=4; type yy=array of real; tt=array of real;...

выдает только одно решение
как сделать что бы выдавало все возможные решения? #pragma argsused #include &lt;stdio.h&gt; #include...

Найдите все значения параметров а и b такие, что система имеет ровно одно решение
|(x^y-1)/(x^y+1)|=a x^2+y^2=b x&gt;0 Понимаю ,что надо раскрыть модуль,а потом ,рассматривая все...

Решение СЛАУ методом простых итераций, задача решена, только написать код осталось
решить СЛАУ с точностью е=10 в степени(-4) 4*x1-x2-x3=2 x1+5*x2-2*x3=4 x1+x2+4*x3=6 ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru