Содержание
Введение 5
1.Постановка задачи 6
2.Описание математической модели решения задачи 7
3.Блок-схема алгоритма 9
4.Описание алгоритма 13
5.Характеристика данных и условные обозначения 15
6.Текст программы 16
7.Контрольный пример 21
8.Анализ результатов 22
Заключение 23
Список используемой литературы 24
Приложение А 25
Приложение Б 26
Введение
Данная задача предназначена для получения (при помощи метода градиента) наиболее точных результатов. Решением задачи, представленной в данной работе, является решение системы линейных уравнений.Результаты вычислений представлены в текстовом файле rezult.txt.
Метод градиента или ,как его еще называют, метод скорейшего спуска,является одним из наиболее распространенным итерационным методом решения линейных систем.Основная идея метода состоит в том, чтобы двигаться к минимуму в направлении наиболее быстрого убывания функции, которое определяется антиградиентом. В градиентном методе с постоянным шагом величина шага, обеспечивающая убывание функции f(x) от итерации к итерации, оказывается очень малой, что приводит к необходимости проводить большое количество итераций для достижения точки минимума. Поэтому методы спуска с переменным шагом являются более экономными.
Правильность работы программы необходимо проверить, воспользовавшись средствами прикладного математического пакета SCILAB.
1.Постановка задачи
Определить токи в ветвях схемы (2.1), если
Необходимо написать программу нахождения токов , в ветвях схемы. Для решения системы линейных алгебраических уравнений воспользоваться методом согласно своему варианту. В итерационных методах выводить количество итераций. Проверить баланс мощностей.
В программе предусмотреть считывание исходных данных с клавиатуры или из текстового файла. Результаты вычислений сохранить в текстовом файле ruzult.txt
Рисунок 2.1 Электрическая схема
2.Описание математической модели решения задачи
Упростив схему (см. рис. 2.1), заменив последовательно и параллельно соединённые резисторы четвёртой и шестой ветвей эквивалентными
(2.1)
Составим на основании законов Кирхгофа систему уравнений для расчета токов во всех ветвях схемы и решим ее
(2.2)
Составим баланс мощностей в исходной схеме (схеме с источником тока), вычислив суммарную мощность источников и суммарную мощность нагрузок (сопротивлений):
Для проверки баланса мощностей
(2.3)
Довольно распространенным итерационным методом решения линейных систем является метод градиента или ,как его еще называют,метод скорейшего спуска. Рассмотрим систему линейных уравнений
(2.4)
с действительной матрицей и столбцом свободных коэффициентов. Тогда и
Следовательно (2.5)
где (2.6)
-невязка вектора и
(2.7)
Алгоритм градиентного метода для решения линейных систем:
1) Выбираем начальное приближение, например
2) Вычисляем невязку по формуле
3) Находим расчетный коэффициент по формуле (2.7). Здесь под выражениями в скобках понимаются скалярные произведения соответствующих векторов.
4) Определяем x по формуле (2.5).
5) Если максимальная невязка системы не превышает точность вычислений , то решение x найдено, иначе переходим к п.2.
3.Блок-схема алгоритма
На рисунке 3.1 изображена блок-схема ,решения СЛАУ методом градиента
На рисунке 3.2 изображена функция умножения массива на массив
На рисунке 3.3 изображена функция умножения матрицы на массив
На рисунке 3.4 изображена функция умножения матрицы на матрицу
На рисунке 3.5 изображена функция транспонирования
На рисунке 3.6 изображена функция main
Рисунок 3.1 Блок-схема метода градиента
Рисунок 3.3 Блок-схема умножение матрицы на массив
Рисунок 3.2 Блок-схема умножения массива на массив
Рисунок 3.4 Блок-схема умножение матрицы на матрицу
Рисунок 3.5 Блок-схема функции транспонирования
Рисунок 3.6 Блок-схема main
4.Описание алгоритма
Функция градиента.
1-Вводим функцию решения систем линейных алгебраических уравнений(СЛАУ) методом градиента
2-3-В значения x записываем значение b
4-Обнуляем количество итераций
5-Вызываем функцию транспонирования матрицы
6- Вызываем функцию умножения двух матриц
7- Вызываем функцию умножения матрицы на массив
8-9-Находим значение R
10- Вызываем функцию умножения матрицы на массив
11- Вызываем функцию умножения массива на массив и находим числитель и знаменатель расчетного коэффициента
12-Вычисляем расчетный коэффициент
13- Вызываем функцию умножения матрицы на массив
14-15-Находим значение E
16-17-Вычисляем значение х
18-Приравниваем к max модуль первого значения R
19-21-Находим максимальный элемент в массиве R
22-Увеличиваем значение К на единицу
23-Если максимальная невязка системы не превышает eps,то решение найдено,иначе переходим к п.7
24-Выводим количество итераций
Блок-схема функции транспонирования матрицы.
1-Вводим функцию транспонирования матрицы
2-Циклом проходим по строкам
3-Циклом проходим по столбцам
4-Получаем транспонированную матрицу
Блок-схема функции скалярного произвидения двух векторов.
1- Вводим функцию умножения двух векторов
2-Обнуляем сумму
3-4-Находим значение умножения двух векторов
Блок-схема функции умножения матрицы на вектор.
1- Вводим функцию умножения матрицы на вектор
2-5-Вычисляем умножение матрицы на вектор
Блок-схема функции умножения матрицы на матрицу.
1- Блок-схема функции умножения матрицы на матрицу
2-5-Вычисляем умножение матрицы на матрицу
5.Характеристика данных и условные обозначения
В таблице 5.1 представлены характеристики данных ,обозначения их в блок-схеме и в программе.
Таблица 5.1:
№ п/п
Наименование данных
Обозначение в блок-схеме
Обозначение в программе
Тип переменных
1
Количество строк в матрице
n
n
int
2
Матрица A
A
A
float**
3
Матрица А транспонированная
At
At
float**
4
Массив x
x
x
float*
5
Матрица С
C
C
float**
6
Массив R
R
R
float*
7
Массив R1
R1
R1
float*
8
Массив F
F
F
float*
9
Массив E
E
E
float*
10
Массив E1
E1
E1
float*
11
Массив b
b
b
float*
12
Значение
e2
e2
float
13
Значение
e3
e3
float
14
Значение
Ik2
Ik2
float
15
Значение
Pist
Pist
float
16
Значение
Pn
Pn
float
17
Значение eps
eps
eps
float
18
Значение max элемента
max
max
float
19
J-й столбец матрицы
j
j
20
I-й столбец матрицы
i
i
21
Количество итераций
k
k
int
6.Текст программы
#include <iostream>
#include <math.h>
#include <fstream>
using namespace std;
void TRANSP(float**At, int n, float**A)
{
int i, j,b;
for(i=0;i<n;i++)
{for(j=0;j<n;j++)
{At[j][i]=A[i][j];}}
}
void matmas (float **A,float *b,int N,float *B)
{
int i,j;
for(i=0;i<N;i++)
{B[i]=0;
for(j=0;j<N;j++)
{B[i]+=A[i][j]*b[j];}}
}
void matmat (float **A,float **B,int N,float **C)
{
int i,j,k;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
for(C[i][j]=0,k=0;k<N;k++)
C[i][j]+=A[i][k]*B[k][j];
}
float masmas(float *x,float *y,int N)
{
float sum;
int i;
sum=0;
for(i=0;i<N;i++)
sum+=x[i]*y[i];
return sum;
}
int GRAD(float **A,float *b,int n,float eps,float *x)
{
int i,j,k,K;
float **C,**At,*R,*R1,*F,*E,*E1,chisl,znam,M,max;
At=new float *[n];
for(i=0;i<n;i++)
At[i]=new float [n];
C=new float *[n];
for(i=0;i<n;i++)
C[i]=new float [n];
R=new float [n];
R1=new float [n];
F=new float [n];
E=new float [n];
E1=new float [n];
for(i=0;i<n;i++)
{x[i]=b[i];}
K=0;
TRANSP(At,n,A);
matmat(A,At,n,C);
do
{
chisl=0;
znam=0;
matmas(A,x,n,R1);
for(i=0;i<n;i++)
{R[i]=0;
R[i]=R1[i]-b[i];}
matmas(C,R,n,F);
chisl=masmas(R,F,n);
znam=masmas(F,F,n);
M=chisl/znam;
matmas(At,R,n,E1);
for(i=0;i<n;i++)
{E[i]=E1[i]*M;}
for(i=0;i<n;i++)
{x[i]-=E[i];}
max=fabs(R[0]);
for(i=0;i<n;i++)
{if(fabs(R[i])>max)max=fabs(R[i]);}
K++;}
while(max>eps);
cout<<«k=»<<K<<endl;
return K;
}
int main(int argc, char *argv[])
{
int i,j,n,m,vvod;
float *R0,*R,**A,*b,*x,**At,eps,e2,e3,Ik2,Pist,Pn;
cout<<«Enter method number :\n 1 — ruchnoy;\n 2 — iz fayla;\n «;
cin>>vvod;
if(vvod==1)
{
cout<<«Vvedite razmer matrici:»<<endl;
cin>>n;
cout<<«Vvedite razmer massiva soprotivleniy:»<<endl;
cin>>m;
cout<<«Vvedite massiv soprotivleniy:»<<endl;
R=new float [m];
for(i=0;i<n;i++)
cin>>R[i];
cout<<«Vvedite massiv b:»<<endl;
b=new float [n];
for(i=0;i<n;i++)
cin>>b[i];
cout<<«Tochnost=»;
cin>>eps;
cout<<endl;
}
else
{
ifstream K;
K.open(«C:\\555\\kursach.txt»,ios::in);
K>>n>>m;
cout<<«razmer matrici=»<<n<<endl;
cout<<«razmer massiva soprotivleniy=»<<m<<endl;
cout<<«massiv soprotivleniy:»<<endl;
R=new float [m];
for(i=0;i<m;i++)
{K>>R[i];
cout<<R[i]<<«\t»;}
K>>e2>>e3>>Ik2;
cout<<endl<<«E2=»<<e2<<endl;
cout<<«E3=»<<e3<<endl;
cout<<«Ik2=»<<Ik2<<endl;
K>>eps;
cout<<endl<<«eps=»<<eps<<endl;
K.close();
}
A=new float *[n];
for(i=0;i<n;i++)
A[i]=new float [n];
for(i=0;i<n;i++)
{for(j=0;j<n;j++)
{A[i][j]=0;}}
A[0][0]=-1;A[0][1]=-1;A[0][4]=1;
A[1][2]=1;A[1][3]=1;A[1][4]=-1;
A[2][1]=1;A[2][2]=-1;A[2][5]=1;
A[3][1]=1;A[3][6]=-1;
A[4][2]=R[2];A[4][3]=-R[3];A[4][5]=R[5];
A[5][0]=R[0];A[5][2]=R[2];A[5][4]=R[4];A[5][5]=R[5];
A[6][0]=-R[0];A[6][1]=R[1];A[6][5]=-R[5];
cout<<«matrica A:»<<endl;
for(i=0;i<n;cout<<endl,i++)
for(j=0;j<n;cout<<«\t»,j++)
cout<<A[i][j];
b=new float [n];
for(i=0;i<n;i++)
{b[i]=0;}
b[3]=Ik2;b[4]=e3;b[5]=e3;b[6]=e2;
cout<<«massiv b:»<<endl;
for(i=0;i<n;cout<<«\t»,i++)
cout<<b[i];
x=new float [n];
GRAD(A,b,n,eps,x);
cout<<endl<<«nassiv X;»<<endl;
for(i=0;i<n;i++)
cout<<x[i]<<endl;
Pist=0;
Pist=35*x[1]+37.5*x[2]+R[1]*x[1]*2;
Pn=0;
for(i=0;i<m;i++)
{Pn+=R[i]*(x[i]*x[i]);}
cout<<«P istochnika=»<<Pist<<endl;
cout<<«P nagruzki=»<<Pn<<endl;
if(Pist==Pn)cout<<«balans moschnostey sovpadaet»<<endl;
else
cout<<«balans moschnostey ne sovpadaet»<<endl;
ofstream E;
E.open(«C:\\rezult.txt»);
E<<«korni matrix:»<<endl;
for(i=0;i<n;i++)
E<<x[i]<<endl;
E.close();
system(«PAUSE»);
return EXIT_SUCCESS;
}
7.Контрольный пример
На рисунке 7.1 изображено консольное окно Scilab ,где вводятся начальные значения
На рисунке 7.2 изображено окно ,где выводятся найденные корни
8.Анализ результатов
Результаты полученые в С++ и математическом пакете Scilabil
Таблица 8.1:
Вычисляемый параметр
Программа
Scilab
Массив Х
-0.678465
1.4023
1.39468
-0.669969
0.724119
-0.00677613
-0.596712
-0.6777444
1.4020154
1.3947256
-0.6704545
0.7242710
-0.0072899
-0.5979846
Мощность источников тока
157.473
157.45336
Мощность нагрузок(сопротивлений)
101.373
101.37275
В данной работе полученные значения токов в ветвях схемы, получились ожидаемыми.Отрицательные значения токов указывают на то , что ток течет в противоположном направлении.
ВВВВолрипргвввплпашВВВлооллоорл Scilab
Заключение
Программа представленная в данной работе, является универсальной,т.к. может реализовать решения систем линейных алгебраических уравнений(СЛАУ) не только для поставленной задачи оптимизации,но и других значений сопротивлений в ветвях схемы.С новыми значениями программа будет составлять системы уравнений по закону Киргоффа и находить значения токов в ветвях схемы,для поставленных значений.
С ее помощью проведены расчеты, проанализированы полученные результаты. Анализ результатов показал, что поставленная задача успешно решена.
Список используемой литературы
1.Методические указания и задания к курсовой работе по курсу «Вычислительная техника и алгоритмические языки» (для студентов специальностей электротехнического факультета). Алексеев Е. Р., Чеснокова О. В., Кучер Т.В.Донецк, ДонНТУ, 2012. – 78 с.
2.Алексеев Е. Р., Чеснокова О. В., Рудченко Е. А. Решение инженерных и математических задач в пакете Scilab. — М.: ALT Linux, 2008. — 257 с
3.Алексеев Е. Р. Программирование на Microsoft Visual C++ и Turbo C++ Explorer. — М.: НТ Пресс, 2007. — 352 с