Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Записка_ПСП_Градиентный спуск C# Клиент-Сервер.docx
Скачиваний:
23
Добавлен:
03.02.2019
Размер:
477.82 Кб
Скачать

Приложение б

(обязательное)

Код клиенткой части

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 глобальный на всё решени

}

}

}