Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Прога на Delphi.C++ или Pascal (https://forum.antichat.xyz/showthread.php?t=104254)

Rastamanka 02.02.2009 00:31

Прога на Delphi,C++ или Pascal
 
В общем ищу софт с исходниками на данных языках.
Тема софта:
1.Решение нелинейных уравнений методом итерации
2.Решение простых линейных уравнений методом итерации

blednii 03.02.2009 19:41

Тебе надо чтоб решение выводил или только твет?

Rastamanka 04.02.2009 11:27

Только ответ.

Flame of Soul 04.02.2009 13:43

Решение системы линейных алгебраических уравнений ( СЛАУ ) методом простых итераций (методом Якоби).
Цитата:

Входные данные - матрица коэффициентов СЛАУ, вектор правых частей, размерность системы.
Выходные данные - вектор решения.

Вспомогательная функция getDiagonal( double **coefficients, double *rightPart, int currRowAndColumn, int numberOfEquation ) преобразует матрицу СЛАУ к диагональному виду с паралелльным преобразованием вектора правых частей.

Не всякая система может быть приведена к системе с матрицей с ненулевой диагональю. Если такое приведение не найдено ( в данном случае оно ищется перестановкой строк ) – система не решается.

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

Исходный код.

PHP код:

#include "stdio.h"
#include "iostream.h"
#include "math.h"

// приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
// возвращает true - если приведение - успешно
bool getDiagonaldouble **coefficientsdouble *rightPartint currColumnint numberOfEquation ) {
    
bool result false;
    
int irow currColumn;
    
double tempItem;

    
// для матрицы 1x1 ответом является ненулевость ее единственного элемента
    
if ( currColumn == numberOfEquation ) {
        
result coefficients[currColumn][currColumn] != 0;
    }
    else {
        
// пока не найдена перестановка приводящая матрицу к виду с ненулевой диагональю и пока мы можем еще просматривать строки ищем перестановку
        
while ( !result && row numberOfEquation ) {
            
// если текущий элемент на диагонали нулевой ищем в столбце дальше ненулевой
            
if ( coefficients[row][currColumn] != ) {
                
// если элемент ненулевой и не лежит на диагонали меняем местами сотвествующие строки в матрице и элементы в векторе прваых частей
                
if ( row != currColumn ) {
                    for ( 
0numberOfEquationi++ ) {
                        
tempItem coefficients[currColumn][i];
                        
coefficients[currColumn][i] = coefficients[row][i];
                        
coefficients[row][i] = tempItem;
                    }                
                    
tempItem rightPart[currColumn];
                    
rightPart[currColumn] = rightPart[row];
                    
rightPart[row] = tempItem;                    
                }
                
// рекурсивный вызов фактически для подматрицы с размерностью на 1 меньше
                
result getDiagonalcoefficientsrightPartcurrColumn 1numberOfEquation );
                if ( 
result ) {
                    break;
                }
            }
            
row ++;
        }
    }

    return 
result;
}

// было ли найдено решение, если да - итог в параметре solution
int iterationdouble **coefficientsdouble *rightPartint numberOfEquationdouble *solutiondouble precision ) {
    
bool result;
    
int ijkstep 1;
    
double temp;
    
doubletempSolution;

    
tempSolution = new double[numberOfEquation];
    
    
// приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
    
result getDiagonalcoefficientsrightPart0numberOfEquation );    

    
// если приведение успешно - работаем дальше
    
if ( result ) {
        
double fault precision 1;

        
// преобразуем матрицу и правую часть для дальнейшего решения
        
for ( 0numberOfEquation++ ) {
            for ( 
0numberOfEquation++ ) {
                if ( 
!= ) {
                    
coefficients[i][j] = - coefficients[i][j] / coefficients[i][i];
                }
            }
            
rightPart[i] = rightPart[i] / coefficients[i][i];
            
coefficients[i][i] = 0;
        }

        
// первое приближение решения - преобразованный вектор правых частей
        
for ( 0numberOfEquation++ ) {
            
solution[i] = rightPart[i];
        }

        
// пока не найдено решение с допустимй погрешнстью или пока не исчерпан лимит шагов... если все расходится например
        
while ( fault precision && step <= 1000 ) {

            
// поиск новой итерации с ее "самоиспользованием" при расчетах            
            
for ( 0numberOfEquation++ ) {
                
tempSolution[j] = 0;
            }
            for ( 
0numberOfEquation++ ) {
                for ( 
0numberOfEquation++ ) {
                    
tempSolution[i] = tempSolution[i] + coefficients[i][j] * solution[j]; 
                }
                
tempSolution[i] = tempSolution[i] + rightPart[i];
            }

            
// расчет погрешности
            
fault 0.0;
            for ( 
0numberOfEquation++ ) {
                
fault fault + (solution[j] - tempSolution[j])*(solution[j] - tempSolution[j]);
            }
            
fault sqrtfault );

            
// сохранение полученной новой итерации
            
for ( 0numberOfEquation++ ) {
                
solution[j] = tempSolution[j];
            }
            
step++;
        }
    }
    else {
        
result 1001;
    }
    

    return 
step;
}


void main() {
    
int ij;
    
int size;
    
double **coefficients, *rightPart, *solutionprecision;

    
cout << "Simple iteration method.\nEnter system dimension: ";
    
cin >> size;

    
coefficients = new double*[size];
    for ( 
0sizei++ ) {
        
coefficients[i] = new double[size];
    }
    
rightPart = new double[size];
    
solution = new double[size];

    for ( 
0size++ ){
        
cout << "Enter " << << " row: ";
        for ( 
0size++ ){
            
cin >> coefficients[i][j];
        }
    }

    
cout << "Enter right part: ";
    for ( 
0size++ ){
        
cin >> rightPart[j];
    }

    
cout << "Enter precision: ";
        
cin >> precision;

    
int steps iterationcoefficientsrightPartsizesolutionprecision );
    if ( 
steps 1000 ) {
        
cout << "Solution for this matrix of coefficients not exist or not found";
    }
    else {
        
cout << "Solution is:\n";
        for ( 
0size++ ){
            
cout << solution[j] << "\n";
        }
        
cout << "Number of step: " << steps;
    }

    
cout << "\nPress \"Enter\" to continue..." << endl
    
getchar();    



Примеры использования (распечатка листинга):


Цитата:

Simple iteration method.
Enter system dimension: 3
Enter 1 row: 10 1 1
Enter 2 row: 2 10 1
Enter 3 row: 2 2 10
Enter right part: 12 13 14
Enter precision: 0.1
Solution is:
0.9946
0.9934
0.9916
Number of step: 4
Press "Enter" to continue...

Flame of Soul 04.02.2009 13:54

Метод простых итераций довольно медленно сходится. Для его ускорения существует метод Зейделя

Цитата:

Входные данные - матрица коэффициентов СЛАУ, вектор правых частей, размерность системы, заданная точность.
Выходные данные - вектор решения.

Вспомогательная функция getDiagonal( double **coefficients, double *rightPart, int currColumn, int numberOfEquation ) преобразует матрицу СЛАУ к виду с ненулевыми диагональными элементами с параллельным преобразованием вектора правых частей.

Не всякая система может быть приведена к системе с матрицей с ненулевой диагональю. Если такое приведение не найдено ( в данном случае оно ищется перестановкой строк ) – система не решается.
Быстрее метода простых итераций.

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

Исходный код:

PHP код:

#include "stdio.h"
#include "iostream.h"
#include "math.h"

// приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
// возвращает true - если приведение - успешно
bool getDiagonaldouble **coefficientsdouble *rightPartint currColumnint numberOfEquation ) {
    
bool result false;
    
int irow currColumn;
    
double tempItem;

    
// для матрицы 1x1 ответом является ненулевость ее единственного элемента
    
if ( currColumn == numberOfEquation ) {
        
result coefficients[currColumn][currColumn] != 0;
    }
    else {
        
// пока не найдена перестановка приводящая матрицу к виду с ненулевой диагональю и пока мы можем еще просматривать строки ищем перестановку
        
while ( !result && row numberOfEquation ) {
            
// если текущий элемент на диагонали нулевой ищем в столбце дальше ненулевой
            
if ( coefficients[row][currColumn] != ) {
                
// если элемент ненулевой и не лежит на диагонали меняем местами сотвествующие строки в матрице и элементы в векторе прваых частей
                
if ( row != currColumn ) {
                    for ( 
0numberOfEquationi++ ) {
                        
tempItem coefficients[currColumn][i];
                        
coefficients[currColumn][i] = coefficients[row][i];
                        
coefficients[row][i] = tempItem;
                    }                
                    
tempItem rightPart[currColumn];
                    
rightPart[currColumn] = rightPart[row];
                    
rightPart[row] = tempItem;                    
                }
                
// рекурсивный вызов фактически для подматрицы с размерностью на 1 меньше
                
result getDiagonalcoefficientsrightPartcurrColumn 1numberOfEquation );
                if (
result) {
                    break;
                }
            }
            
row ++;
        }
    }

    return 
result;
}

// было ли найдено решение, если да - итог в параметре solution
int iterationdouble **coefficientsdouble *rightPartint numberOfEquationdouble *solutiondouble precision ) {
    
bool result;
    
int ijkstep 1;
    
double temp;
    
doubletempSolution;

    
tempSolution = new double[numberOfEquation];
    
    
// приведение матрицы коэффициентов к виду с ненулевой диагональю и соответствующее изменение вектора правых частей
    
result getDiagonalcoefficientsrightPart0numberOfEquation );    

    
// если приведение успешно - работаем дальше
    
if ( result ) {
        
double fault precision 1;

        
// преобразуем матрицу и правую часть для дальнейшего решения
        
for ( 0numberOfEquation++ ) {
            for ( 
0numberOfEquation++ ) {
                if ( 
!= ) {
                    
coefficients[i][j] = - coefficients[i][j] / coefficients[i][i];
                }
            }
            
rightPart[i] = rightPart[i] / coefficients[i][i];
            
coefficients[i][i] = 0;
        }

        
// первое приближение решения - преобразованный вектор правых частей
        
for ( 0numberOfEquation++ ) {
            
solution[i] = rightPart[i];
        }

        
// пока не найдено решение с допустимй погрешнстью или пока не исчерпан лимит шагов... если все расходится например
        
while ( fault precision && step <= 1000 ) {
            
            
// поиск новой итерации
            
for ( 0numberOfEquation++ ) {
                
tempSolution[j] = 0;
            }
            for ( 
0numberOfEquation++ ) {
                for ( 
0i++ ) {
                    
tempSolution[i] = tempSolution[i] + coefficients[i][j] * tempSolution[j]; 
                }
                for ( 
inumberOfEquation++ ) {
                    
tempSolution[i] = tempSolution[i] + coefficients[i][j] * solution[j]; 
                }
                
tempSolution[i] = tempSolution[i] + rightPart[i];
            }

            
// расчет погрешности
            
fault 0;
            for ( 
0numberOfEquation++ ) {
                
fault fault + (solution[j] - tempSolution[j])*(solution[j] - tempSolution[j]);
            }
            
fault sqrtfault );

            
// сохранение полученной новой итерации
            
for ( 0numberOfEquation++ ) {
                
solution[j] = tempSolution[j];
            }
            
step++;
        }
    }
    else {
        
result 1001;
    }
    

    return 
step;
}


void main() {
    
int ij;
    
int size;
    
double **coefficients, *rightPart, *solutionprecision;

    
cout << "Simple iteration method.\nEnter system dimension: ";
    
cin >> size;

    
coefficients = new double*[size];
    for ( 
0sizei++ ) {
        
coefficients[i] = new double[size];
    }
    
rightPart = new double[size];
    
solution = new double[size];

    for ( 
0size++ ){
        
cout << "Enter " << << " row: ";
        for ( 
0size++ ){
            
cin >> coefficients[i][j];
        }
    }

    
cout << "Enter right part: ";
    for ( 
0size++ ){
        
cin >> rightPart[j];
    }

    
cout << "Enter precision: ";
        
cin >> precision;

    
int steps iterationcoefficientsrightPartsizesolutionprecision );
    if ( 
steps 1000 ) {
        
cout << "Solution for this matrix of coefficients not exist or not found";
    }
    else {
        
cout << "Solution is:\n";
        for ( 
0size++ ){
            
cout << solution[j] << "\n";
        }
        
cout << "Number of step: " << steps;
    }

    
cout << "\nPress \"Enter\" to continue..." << endl
    
getchar();    



Примеры использования (распечатка листинга):

Цитата:

Simple iteration method.
Enter system dimension: 3
Enter 1 row: 10 1 1
Enter 2 row: 2 10 1
Enter 3 row: 2 2 10
Enter right part: 12 13 14
Enter precision: 0.1
Solution is:
1.00068
0.997944
1.00028
Number of step: 3
Press "Enter" to continue...


PS: Больше не чем помочь немогу


Время: 15:23