- •Введение
- •1 Средства для решения задач нелинейных алгебраических уравнений в распределенной вычислительной среде
- •1.1 Понятие распределенных вычислений как способа решения трудоёмких вычислительных задач с использованием нескольких компьютеров
- •1.2 Распределенные вычисления на основе стека
- •1.3 Понятие клиент-серверных систем
- •1.4 Методы и их модификации для решения систем нелинейных уравнений
- •2 Алгоритмы и методы для решения нелинейных алгебраиеских уравнений на основе метода натуральных градиентов
- •2.1 Техническое задание для написания программы для решения систем нелинейных алгебраических уравнений методом натуральных градиентов
- •2.2 Aлгоритм метода натуральных градиентов
- •2.3 Алгоритмы линейного и распределенного решения
- •2.4 Алгоритм синтаксического анализатора, разработанного на основе обратной польской записи
- •2.5 Математическая модель распределенного вычисления Якобиана отображения
- •2.6 Описание основных функций клиент-серверного приложения
- •3 Программный комплекс для решени нелинейных алгебраических уравнений методом натуральных градиентов
- •3.1 Руководство пользователя
- •3.2 Результат исследование зависимости времени нахождения решения от размерности системы и способа решения
- •Заключение
- •Список использованных источников
- •Приложение а
- •Код сервеной части
- •Приложение б
- •Код клиенткой части
- •Приложение в
- •Данные из тестовых файлов
- •Приложение г
Приложение б
(обязательное)
Код клиенткой части
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace client
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
int n;
String[] Urav;
// Решение выражения выражения
// при помощи обратной польской записи
double solve (String s)
{
s=s.Trim();
double rez=0.0;
if (double.TryParse(s,out rez))
{
return rez;
}
if (String.IsNullOrEmpty(s))
{
return 0.0;
}
PostfixNotationExpression post=new PostfixNotationExpression();
return (double)post.result(s);
}
// Заменяем тригонометрические функции на вычисленные выражения
private void ChangeFun (ref String s, int numFun)
{
String[] funs=new String[] {"sin","cos","ctg","tg"}; // сначала ctg, потом tg обязательно!!!!!!!!!
String fun=funs[numFun];
// Избавляемся от sin cos tg ctg
int pos=-1;
while (s.IndexOf(fun)>=0)
{
pos=s.IndexOf(fun);
int i0=pos+1;
while(s[i0]!='(') i0++;
int j=i0+1;
int level=0;
while (s[j]!=')' || level>0) {
if (s[j]=='(') { level++; j++; } else
if (s[j]==')') level--; else j++;
}
int k=i0+1;
while (s[k]==' ') k++;
// от k до j-1
string part;
part=s.Substring(k,j-1-k+1).Trim();
// Убираем лишние скобки
if (part[0]=='(' && part[part.Length-1]==')')
{
part=part.Substring(1,part.Length-2);
}
// Решаем в скобках тригонометрической функции
double v0=solve(part);
// Вычисляем значение тригонометричекой функции
double v=0.0;
switch (numFun)
{
case 0: v=Math.Sin(v0); break;
case 1: v=Math.Cos(v0); break;
case 2: v=Math.Tan(v0); break;
case 3:
{
double t=Math.Tan(v0);
if (Math.Abs(t)<0.00000001) v=1000000000; else
v=1.0/t;
};
break;
};
// Вырезаем тригонометрическую функцию от pos до j
string replace=s.Substring(pos,j-pos+1);
double dd=Math.Round(v,6);
if (dd>100000000) dd=100000000;
// Заменяем функцию на вычисленное значение
s=s.Replace(replace,dd.ToString());
}
}
// Вычисляем производуню по j-ой переменной в i-ой функции
// Значение Якобиана [i,j]
double fYakobi (int i, int j, double[,] x)
{
// Простейшая формула численного дифференцирования
double h=0.0001;
double f2=func(Urav[i],x);
x[j,0]+=h;
double f1=func(Urav[i],x);
return (f1-f2)/h;
}
// Значение функции, записанной в строке
double func (String s,double[,] x)
{
// Добавляем знак (*) между, пример: x001x005 --> x001*x005
for (int j=0; j<=9; j++)
{
while (s.IndexOf(j.ToString()+"x")>=0)
{
s=s.Replace(j.ToString()+"x",j.ToString()+"*x");
}
}
// Заменяем
s=s.Replace(")c",")*c");
s=s.Replace(")s",")*s");
s=s.Replace(")t",")*t");
s=s.Replace(")(",")*(");
// Заменяем числами, пример x001*x005 --> 1.2*4.3
for (int j=0; j<x.Length; j++)
{
String num=(j+1).ToString();
while (num.Length<3) num="0"+num;
String ss=String.Format("{0:f8}",x[j,0]);
if (x[j,0]<0)
{
s=s.Replace("x"+num,"(0,000000001"+ss+")"); // отрицательное число ставим в скобках
}
else
{
s=s.Replace("x"+num,ss);
}
}
// Замена всех тригонометрических функций
for (int j=0; j<4; j++)
{
ChangeFun (ref s, j);
}
s=s.Trim();
s=s.Replace(" "," ");
String[] mas=s.Split(' ');
double val=0.0;
foreach (String member in mas)
{
val+=solve(member.Trim());
}
return val;
}
void Button1Click(object sender, EventArgs e)
{
// Устанавливаем для сокета локальную конечную точку
IPHostEntry ipHost = Dns.GetHostEntry("localhost");
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, int.Parse(textBox1.Text));
// Создаем сокет Tcp/Ip
Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Назначаем сокет локальной конечной точке и слушаем входящие сокеты
sListener.Bind(ipEndPoint);
sListener.Listen(10);
Socket handler;
listBox1.Items.Clear();
while(true) {
// Ожидаем соединения
handler = sListener.Accept();
// Получаем n
byte[] bytes = new byte[2];
handler.Receive(bytes);
n=(int)bytes[1]; // КОличество неизвестных
int part=(int)bytes[0]; // Номер части Якобиана для расчета
// Отправляем ответ
byte[] m_answer=new byte[1];
handler.Send(m_answer);
double[,] x0=new double[n,1];
double[,] f0=new double[n,1];
double[,] w0=new double[n,n];
double[,] x1=new double[n,1];
double[,] f1=new double[n,1];
double[,] w1=new double[n,n];
// Выводим на форму
listBox1.Items.Add("n="+n.ToString());
Application.DoEvents();
handler.Shutdown(SocketShutdown.Both);
handler.Close();
// Принимаем уравнения
Urav=new String[n];
for (int i=0; i<n; i++)
{
handler = sListener.Accept();
bytes = new byte[1000];
int rec=handler.Receive(bytes);
Urav[i]=new string(Encoding.Unicode.GetChars(bytes,0,rec));
// Отправляем ответ
m_answer=new byte[1];
handler.Send(m_answer);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
// Вывод уравнений
foreach (String s in Urav) listBox1.Items.Add(s);
listBox1.Items.Add("============================");
Application.DoEvents();
int middle=n/2; // часть
// Цикл получения x1 и выдача части Якобиана
// Это повторяется многократно
while (true)
{
// Принимаем x1
handler = sListener.Accept();
bytes = new byte[1000];
int rec1=handler.Receive(bytes);
// Отправляем ответ
m_answer=new byte[1];
handler.Send(m_answer);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
int k=0;
String s6="";
for (int i = 0; i < rec1; i+=8)
{
x1[k,0] = BitConverter.ToDouble(bytes,i);
s6+=Math.Round(x1[k,0],4).ToString()+" ";
k++;
};
listBox1.Items.Add("x: "+s6);
Application.DoEvents();
if (part==0)
{
// Расчет якобиана 1-ой части
for (int i=0; i<middle; i++)
{
String s2="";
for (int j=0; j<n; j++)
{
w1[i,j]=fYakobi(i,j,x1);
s2+=Math.Round(w1[i,j],5).ToString()+" ";
}
listBox1.Items.Add("w"+i+": "+s2);
handler = sListener.Accept();
byte[] bytes2 = new byte[2];
handler.Receive(bytes2);
// Отправляем ответ
double[] mas=new double[n];
for (int v=0; v<n; v++) mas[v]=w1[i,v];
byte[] sendByte=new byte[mas.Length*8];
Buffer.BlockCopy(mas, 0, sendByte, 0, sendByte.Length);
handler.Send(sendByte);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
else
{
// Расчет якобиана 2-ой части
for (int i=middle; i<n; i++)
{
String s2="";
for (int j=0; j<n; j++)
{
w1[i,j]=fYakobi(i,j,x1);
s2+=Math.Round(w1[i,j],5).ToString()+" ";
}
listBox1.Items.Add("w"+i+": "+s2);
handler = sListener.Accept();
byte[] bytes3 = new byte[2];
handler.Receive(bytes3);
// Отправляем ответ
double[] mas=new double[n];
for (int v=0; v<n; v++) mas[v]=w1[i,v];
byte[] sendByte=new byte[mas.Length*8];
Buffer.BlockCopy(mas, 0, sendByte, 0, sendByte.Length);
handler.Send(sendByte);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
};
// Получаем контрольный байт
handler = sListener.Accept();
byte[] bytes7 = new byte[2];
handler.Receive(bytes7);
// Отправляем ответ
byte[] m_answer7=new byte[1];
handler.Send(m_answer7);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
if (bytes7[0]==3) break;// выход
}; //while
listBox1.SelectedIndex=listBox1.Items.Count-1;
}; // while глобальный на всё решени
}
}
}