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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
nokiago
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
#1

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

02.04.2016, 12:26. Просмотров 577. Ответов 22
Метки нет (Все метки)

Здравствуйте, как можно создать СЛАУ большой размерности в виде матрицы в c++, чтобы система имела только одно решение?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.04.2016, 12:26
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Создать СЛАУ размерности 1000х1000 в С++, чтобы система имела только одно решение (C++):

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

выдает только одно решение - C++
как сделать что бы выдавало все возможные решения? #pragma argsused #include <stdio.h> #include <stdlib.h> int A, fl; int...

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

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

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

Выходит только одно значение. Что сделать, чтобы выходил массив? - VBA
Function fun32(m As Integer, n As Integer) For x = 2 To 3 Step 0.2 s = 2 ^ ((m * x) / (n * Log(x))) fun32 = s Next End Function ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.04.2016, 18:10 #2
Можно плясать от печки. Создать единичную матрицу, затем применить серию преобразований, включающих умножение строки на случайный ненулевой коэффициент и сложение с другой случайно выбранной строкой.
1
nokiago
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:14  [ТС] #3
Nick Alte, можете подсказать как?
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.04.2016, 18:16 #4
Цитата Сообщение от nokiago Посмотреть сообщение
можете подсказать как?
Надо разъяснить, что такое умножение строки матрицы на число? Или как складывать одну строку с другой?
0
nokiago
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:23  [ТС] #5
Nick Alte, нет, я не понимаю, как из того, что вы сказали, сделать нужную матрицу
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.04.2016, 18:42 #6
Цитата Сообщение от nokiago Посмотреть сообщение
нет, я не понимаю, как из того, что вы сказали, сделать нужную матрицу
Попробую выразиться попроще.
Сначала берём единичную матрицу (ту, в которой везде нули, а на главной диагонали - единицы). У неё заведомо есть ровно одно решение.
Начинаем наугад брать разные строки, умножать их на случайно выбранные (но ненулевые) числа и складывать с другими наугад выбранными строками. Каждое такое преобразование не "испортит" матрицу в том смысле, что у неё останется единственное решение.
Делаем много-много таких преобразований. Десятки тысяч. Сколько терпения хватит. Теперь матрица набита огромным количеством разнообразных случайных чисел во всех местах, но у неё по-прежнему ровно одно решение.
1
nokiago
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 18:52  [ТС] #7
Nick Alte, вот сейчас вроде бы всё полностью понял, спасибо большое. А на практике только не знаю, как складывать с рандомными строками. Единичную матрицу сделаю, строки умножу через rand, при этом исключив нули. А вот как сложить с рандомной строкой рандомную строку?
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
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
nokiago
0 / 0 / 0
Регистрация: 28.05.2015
Сообщений: 39
02.04.2016, 19:04  [ТС] #9
Nick Alte, Спасибо! попробую это сделать на практике
0
nokiago
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
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
04.04.2016, 20:00 #11
Цитата Сообщение от nokiago Посмотреть сообщение
Я правильно мыслю,
Не совсем правильно, если не по сути, то в формулировке. Матрица - это преобразование, которое из любого набора входных чисел A делает некий выходной набор чисел B. Единичная матрица, с которой начинается процесс, выдаёт на выходе то же, что получает на входе.
"Решением" матрицы является обратная матрица, которой на вход можно подать B и получить в результате A.
После описанных мной умножений-сложений матрица будет содержать некоторое произвольное линейное преобразование. Её можно будет решить и получить обратную матрицу.
То, что сейчас в программе делается с массивом B - отслеживаются вносимые в матрицу преобразования и воспроизводятся. То есть, это некий способ вручную воспроизвести умножение исходного вектора на полученную матрицу.

Цитата Сообщение от nokiago Посмотреть сообщение
и ещё один вопрос, можно ли как-то сделать так, чтобы коэффициенты в матрице и в векторе были не такими огромными
Для начала надо правильно вычислять коэффициент K. Сейчас он всегда равен 0.1: не забываем, что функция rand() возвращает целые числа, и операция % тоже целочисленная. Если позволить ему принимать отрицательные значения (например, в диапазоне -1;1, или -2;2, или даже -5;5), то итоговые коэффициенты в матрице окажутся более-менее сбалансированными.
0
nokiago
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
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
04.04.2016, 22:57 #13
Цитата Сообщение от nokiago Посмотреть сообщение
но почему они все целочисленные получаются?
Потому что вырастают из целочисленных операций. Так, остаток от деления любого числа на 1 - ноль. А ведь именно это и означает rand()%1.
К примеру, если мы хотим получать число в диапазоне от -5 до 5 с шагом 0.001, надо написать:
Код
K = ((rand() % 10001) - 5000) / 1000.0;
Выражение в скобках даст нам целое число от -5000 до 5000, а деление на вещественную константу даст вещественный результат. Конечно, надо будет проверить, чтобы он был ненулевой.

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

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

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

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

Цитата Сообщение от nokiago Посмотреть сообщение
но насколько я знаю, должно выполняться условие сходимости.
Тут надо в матан залезать, но вроде бы на такой матрице должно хорошо сходиться, там нет дикого разброса коэффициентов и прочих неприятных вещей.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2016, 23:16
Привет! Вот еще темы с ответами:

Как сделать, чтобы не отображались посторонние фигуры, а вращалось только одно изображение? - Delphi
Подскажите, пожалуйста, как сделать, чтобы не отображались посторонние фигуры, а вращалось только одно изображение. И как задать...

СЛАУ ошибка в программе (решение слау метод Зейделя) - MathCAD
Доброе время суток помогите найти ошибку в программе (решение слау метод Зейделя)

Как создать таблицу, чтобы одно из полей автоматически увеличивалось на 1 - SQL Server
Как создать таблицу, чтобы одно из полей автоматически увеличивалось на 1. Например нужно создать таблицу TEST одно поле которой (типа...

Как сделать, чтобы панель имела фокус? - Java
Помогите разобраться с: 1)Не работает и ничего не говорит такой код, что и где нужно ещё добавить, изменить, удалить?: ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
04.04.2016, 23:16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru