Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_Курсовой 18_06_12.docx
Скачиваний:
9
Добавлен:
09.11.2019
Размер:
829.5 Кб
Скачать
  1. Нисходящее проектирование

    1. Основной алгоритм

АЛГОРИТМ Курсовой_проект

<Описание переменных> (см. спецификацию)

НАЧАЛО

ЕСЛИ (ввод с файла) ТО

Выбор файла и создание потока(1.1)

перепись 1-го графа с частичным контролем из файла на экран; (1.2)

ЕСЛИ (ошибка) ТО

вывод («В данных на файле ошибка!»);

Выход;

КЕСЛИ

перепись 2-го графа с частичным контролем из файла на экран;

ЕСЛИ (ошибка) ТО

вывод («В данных на файле ошибка!»);

Выход;

КЕСЛИ

Закрыть поток.

КЕСЛИ

Ввод с экрана 1-го графа с полным контролем и построением матрицы смежности MS1 (1.3)

ЕСЛИ (ошибка) ТО

вывод («В данных на форме ошибка»)

Выход;

КЕСЛИ

Ввод с экрана 2-го графа с полным контролем и построением матрицы смежности

MS2

ЕСЛИ (ошибка) ТО

вывод («В данных на форме ошибка»)

Выход;

КЕСЛИ

Расчет диаметра 1-го графа d1 (1.4)

Расчет диаметра 2-го графа d2;

ЕСЛИ (d1=dr2) ТО

вывод («Графы эквивалентны»);

ИНАЧЕ

вывод («Графы не эквивалентны»);

КЕСЛИ

КОНЕЦ

Из текста алгоритма видно, что в нем имеется 4 подзадачи (рис.21).

Рис. 17

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

1-й способ

Продолжаем раскрывать содержание подзадач. Если в процессе раскрытия подзадачи на определенном уровне нет внутренних подзадач, то эту подзадачу подставляем в верхний уровень. Подстановка осуществляется следующим образом. Текст подзадачи превращаем в комментарий, а ниже располагаем вызов подзадачи с фактическими параметрами. Если все подзадачи нижнего уровня подставлены в верхние уровни, после этого записываем все алгоритмы на языке программирования и отлаживаем проект.

2-й способ

Подзадачи (1.1) – (1.4) реализуются «заглушками». Заглушка – это алгоритм (метод), написанный на языке программирования с правильным заголовком и с упрощенным либо пустым блоком. Указанные заглушки подставляем в основной алгоритм, а затем записываем на языке программирования и вместе с «заглушками» отлаживаем программу. После отладки детализируем отдельные подзадачи таким же способом.

Проектирование будем выполнять вторым способом. Напомним, что при проектировании подзадач имеется три варианта: реализация подзадачи в виде блока, в виде метода без типа и в виде метода с возвратом значения некоторого типа.

Реализация подзадачи (1.1). Выбор файла и создание потока (подзадачу реализуем в виде блока)

Программирование будем выполнять на языке C#.

Переменные

string filename;

{

if (openFileDialog1.ShowDialog == DialogResult.OK)

{

filename = openFileDialog1.FileName;

//создание потока и подсоединение к файлу

Potok = new StreamReader(filename);

}

else

{

MessageBox.Show( “Файл не выбран!”);

return ;

}

Реализация подзадачи (1.2). Ввод графа с файла на экран с частичным контролем. Подзадачу реализуем в виде метода без типа.

Для размещения параметров графа n и m используем компоненты NumericUpDown, что позволяет уменьшить количество проверок, а для размещения FO – представления, компоненту TextBox. Для имитации ошибок данных, при переносе с файла, на форме временно разместим компоненты типа CheckBox (CB1, CB2).

public void Move_Gr_fileToEcran (StreamReader Potok, NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFО, ref bool error)

{

MessageBox.Show(“Выполняется перенос графа с файла на экран”);

error=CB1.Checked;

}

Реализация подзадачи (1.3). Ввод данных с экрана с контролем и построением матрицы смежности. Подзадачу реализуем в виде метода без типа.

public void Input_GrInEkran (NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFO, ref int n, ref int m, ref int [,] MS, ref bool error)

{

MessageBox.Show (“Выполняется ввод графа с экрана и построение матрицы”);

error=CB2.Checked;

}

Реализация заглушки (1.4). Расчет диаметра графа. Подзадачу реализуем в виде метода с типом результата (целое число)

public int Diametr( int[,]MS)

{

MessageBox.Show(“Находим диаметр графа”);

return 2;

}

Подставляем «заглушки» в основной алгоритм

АЛГОРИТМ Курсовой_проект

<Описание переменных> (см. спецификацию)

string filename;

bool error;

НАЧАЛО

ЕСЛИ (ввод с файла) ТО

//Выбор файла и создание потока (1.1)

if (openFileDialog1.Show == DialogResult.OK)

{

filename = openFileDialog1.Filename;

//создание потока и подсоединение к файлу

StreamReader Potok = new StreamReader(filename);

}

else

{

MessageBox.Show( “Файл не выбран!”);

Return ;

}

//перепись 1-го графа с частичным контролем из файла на экран; (1.2)

Move_Gr_fileToEcran ( Potok, nUDn1, nUDm1, tBFО1, ref error);

ЕСЛИ (error) ТО

вывод («В данных на файле ошибка!»);

Выход;

КЕСЛИ

//перепись 2-го графа с частичным контролем из файла на экран;

Move_Gr_fileToEcran ( Potok, nUDn1, nUDm1, tBFО1, ref error);

ЕСЛИ (error) ТО

вывод («В данных на файле ошибка!»);

Выход;

КЕСЛИ

Potok.Close();

КЕСЛИ

//Ввод с экрана 1-го графа с полным контролем и построением матрицы смежности //MS1 (1.3)

Input_GrInEkran ( nUDn1, nUDm1, tBFO1, ref n1, ref m1, ref MS1, ref error);

ЕСЛИ (error) ТО

вывод («В данных на форме ошибка»)

Выход;

КЕСЛИ

//Ввод с экрана 2-го графа с полным контролем и построением матрицы смежности

// MS2

Input_GrInEkran ( nUDn2, nUDm2, tBFO2, ref n2, ref m2, ref MS2, ref error);

ЕСЛИ (error)) ТО

вывод («В данных на форме ошибка»)

Выход;

КЕСЛИ

//Расчет диаметра 1-го графа r1 (1.4)

//Расчет диаметра 2-го графа r2;

ЕСЛИ (/*d1= d2*/ Diametr( MS1)== Radius( MS2)) ТО

вывод («Графы эквивалентны»);

ИНАЧЕ

вывод («Графы не эквивалентны»);

КЕСЛИ

КОНЕЦ

Записываем основной алгоритм на С# и вместе с заглушками отлаживаем его.

public void Kyrs_proekt()

{

<Описание переменных> (см. спецификацию)

string filename;

bool error;

if (/*ввод с файла*/radioGroup1.Checked)

{

//Выбор файла и создание потока (1.1)

if (openFileDialog1.Show == DialogResult.OK)

{

filename = openFileDialog1.Filename;

//создание потока и подсоединение к файлу

StreamReader Potok = new StreamReader(filename);

}

else

{

MessageBox.Show( “Файл не выбран!”);

Return ;

}

//перепись 1-го графа с частичным контролем из файла на экран; (1.2)

Move_Gr_fileToEcran ( Potok, nUDn1, nUDm1, tBFО1, ref error);

if (error)

{

MessageBox.Show (“В данных на файле ошибка!”);

return;

}

//перепись 2-го графа с частичным контролем из файла на экран;

Move_Gr_fileToEcran ( Potok, nUDn1, nUDm1, tBFО1, ref error);

if (error)

{

MessageBox.Show (“В данных на файле ошибка!”);

return;

}

Potok.Close();

}

//Ввод с экрана 1-го графа с полным контролем и построением матрицы смежности //MS1 (1.3)

Input_GrInEkran ( nUDn1, nUDm1, tBFO1, ref n1, ref m1, ref MS1, ref error);

if (error)

{

MessageBox.Show (“В данных на форме ошибка”);

return;

}

//Ввод с экрана 2-го графа с полным контролем и построением матрицы смежности

// MS2

Input_GrInEkran ( nUDn2, nUDm2, tBFO2, ref n2, ref m2, ref MS2, ref error);

if (error))

{

MessageBox.Show (“В данных на форме ошибка”);

return;

}

//Расчет диаметра 1-го графа r1 (1.4)

//Расчет диаметра 2-го графа r2;

if (/*d1= d2*/ Diametr( MS1)== Radius( MS2))

MessageBox.Show (“Графы эквивалентны”);

else

MessageBox.Show (“Графы не эквивалентны”);

}

Приступаем к проектированию подзадачи (1.2). Перепись графа с файла на экран с частичным контролем.

Move_Gr_fileToEcran (StreamReader Potok. NumericUpDown nUDn, NumericUpDown nUDm, TextBox tbFO, ref bool error)

НАЧАЛО

Перенос чисел n и m на форму в компоненты nUDn, nUDm.

Считываем строку с файла и преобразуем ее в вектор строк (vect).

В vect[0] будет n, а в vect[1] будет m (см. в спецификации размещение данных).

Выполняем контроль n и m и заносим их в компоненты nUDn и nUDm.

Перенос FO на форму в компоненту tbFO.

Считываем FO (может занимать несколько строк) с файла в строку S и преобразуем ее в вектор строк (vect), который переписываем в tbFO без контроля.

КОНЕЦ

В этой подзадаче есть подзадачи, но они реализуются простыми средствами языка C#, без оформления их отдельными методами.

Реализуем данную подзадачу на C#.

public void Move_Gr_fileToEcran (StreamReader Potok. NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFO, ref bool error)

{

//Перенос чисел n и m на форму в компоненты numericUpDown.

//Считываем строку с файла и преобразуем ее в вектор строк (vekt).

//В vect[0] будет n, а в vect[1] будет m (см. в спецификации размещение данных)

har ch= ‘ ‘;

string str =Potok.ReadLine();

string [] vect=str.split();

n = int.Parse(vect[0]);

m = int.Parse(vect[1]);

//Выполняем контроль n и m и заносим их в компоненты nUDn и nUDm

if ((n < 1) || (n > 20))

{

MessageBox.Show ("Ошибка ввода количества вершин графа");

error = true;

return;

}

nUDn.Value = n;

if ((m < 1) || (m > 50))

{

MessageBox.Show ("Ошибка ввода количества ребер графа");

error = true;

return;

}

nUDm.Value = m;

//Перенос FO на форму в компоненту tbFO.

//Считываем FO (может занимать несколько строк) с файла в строку S и преобразуем //ее в вектор строк (vect), который переписываем в tbFO без контроля.

string strp =””;

while ((str = Potok.ReadLine()) != “”)

strp += str;

vect = strp.Split(ch);

int k = vect.Length;

tBFO.Clear();

for(int i=0; i<k;i++)

tBFO.Lines[i]=vect[i];

}

Этот метод записываем вместо заглушки (1.2).

Приступаем к проектированию подзадачи (1.3). Ввод данных с экрана с контролем и построением матрицы смежности

Input_GrInEkran (NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFO, ref int n, ref int m, ref [,] MS, ref bool error)

НАЧАЛО

Считываем с экрана n, m;

n =(int) nUDn.Value;//преобразуем в целое, так как Value типа decimal

m = (int)nUDm.Value ;

Проверка количества элементов FO.

int k=tBFO.Lines.Length;

ЕСЛИ k<> n+2*m ТО

Вывод (“Количество элементов FO неверно”);

error=true;

Выход;

КЕСЛИ

//обнуляем матрицу смежности

ДЛЯ i = 1 ДО n ЦИКЛ

ДЛЯ j = 1 ДО n ЦИКЛ

MS [i,j]=0;

КЦИКЛ

КЦИКЛ

Считываем FO и строим матрицу смежности (1.31 на рис. 22).

Контроль симметричности матрицы смежности (1.32 на рис. 22).

КОНЕЦ

Рис. 22

В этом алгоритме есть две подзадачи (1.31) и (1.32). Реализуем их в виде методов с типом.

Реализация подзадачи (1.31) - считывание FO и построение матрицы смежности.

bool CreatMS(TextBox tBFO,ref int [,] MS)

НАЧАЛО

L=0;//индекс строки в компоненте tBFO

int n =(int)Math.Sqrt(MS.Length);

ДЛЯ i = 1 ДО n ЦИКЛ //по вершинам графа

// считываем первую вершину j, следующую за i

j = int,Parse( tBFO.Lines [L]);

//контроль j

ЕСЛИ (j<0) или (j>n) ТО

Вывод («Элемент FO - неверный»);

Выход true;

КЕСЛИ

//считывание остальных вершин j, следующих за i

ПОКА ( j <>0) ЦИКЛ

MS[i,j]:=1;

L=L+1;

j = int.Parse(tBFO.Lines [L]);

//контроль j

ЕСЛИ (j<0) или (j>n) ТО

Вывод («Элемент FO - неверный»);

Выход true;

КЕСЛИ

КЦИКЛ

L=L+1;

КЦИКЛ

Выход false

КОНЕЦ

Реализация подзадачи (1.32) – проверка симметричности матрицы смежности.

bool SimetrMS(int [,] MS,ref string msg)

НАЧАЛО

int n =(int)Math.Sqrt(MS.Length);

msg=””;

ДЛЯ i = 1 ДО n ЦИКЛ

ДЛЯ j = i+1 ДО n ЦИКЛ

ЕСЛИ MS [i,j]<> MS [j,i] ТО

msg =msg +”[“+значения(I,j и j,i)+”]”;

КЕСЛИ

ЕСЛИ msg<>”” ТО

msg =”Проверить ребра ”+msg

Выход true;

ИНАЧЕ

Выход false;

КЕСЛИ

КОНЕЦ

В подзадачах (1.31) и (1.32) нет других подзадач. Запишем их на C# и подставим в подзадачу (1.3).

public bool CreatMS(TextBox tBFO,ref int [,] MS)

{

int L=0;//индекс строки в компоненте tBFO

int n=(int)Math.Sqrt(MS.Length);

for(int i = 0; i< n ; i++) //по вершинам графа

{

// считываем первую вершину j, следующую за i

j = int,Parse( tBFO.Lines [L]);

//контроль j

If((j<0) || (j>n))

{

MessageBox.Show («Элемент FO - неверный»);

return false;

}

//считывание остальных вершин j, следующих за i

while( j <>0)

{

MS[i,j-1]:=1;

L++;

j = int.Parse(tBFO.Lines [L]);

//контроль j

If((j<0) || (j>n) )ТО

{

MessageBox.Show («Элемент FO - неверный»);

return false;

}

}

L=L+1;

}

return true;

}

public bool SimetrMS(int [,] MS,ref string msg)

{

int n=(int)Math.Sqrt(MS.Length);

for(int i = 0; i<n ;i++)

for(int j = i+1;j< n; j++)

if( MS [i,j] != MS [j,i])

msg =msg +”[(“+i.ToString()+”,” + j.ToString()+”)и(”+j.ToString()+”,” + i.ToString()+”)]”;

if( msg !=””)

{

msg =”Проверить ребра ”+msg;

return false;

}

else

return true;

}

На рис. 23 отобразим записанные задачи на C#:

Рис. 23

Подставляем эти задачи в подзадачу (1.3):

Input_GrInEkran (NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFO, ref int n, ref int m, ref [,] MS, ref bool error)

НАЧАЛО

Считываем с экрана n, m.

n =(int) nUDn.Value;//преобразуем в целое, так как Value типа decimal

m = (int)nUDm.Value ;

Проверка количества элементов FO.

int k=tBFO.Lines.Length;

ЕСЛИ k<> n+2*m ТО

Вывод (“Количество элементов FO неверно”);

error=true;

Выход;

КЕСЛИ

//обнуляем матрицу смежности

ДЛЯ i = 1 ДО n ЦИКЛ

ДЛЯ j = 1 ДО n ЦИКЛ

MS [i,j]=0;

КЦИКЛ

КЦИКЛ

//Считываем FO и строим матрицу смежности (1.31)

ЕСЛИ не CreatMS(tBFO,ref MS) ТО

error=true

Выход

КЕСЛИ

//Контроль симметричности матрицы смежности (1.32)

string msg=””;

ЕСЛИ не SimetrMS(MS,ref msg)ТО

Вывод (msg);

error=true;

Выход;

КЕСЛИ

КОНЕЦ

Записываем подзадачу (1.3) на C# , подставляем ее вместо заглушки (1.3) и отлаживаем основной алгоритм.

public void Input_GrInEkran (NumericUpDown nUDn, NumericUpDown nUDm, TextBox tBFO, ref int n, ref int m, ref int [,] MS, ref bool error)

{

//Считываем с экрана n, m.

n =(int) nUDn.Value;//преобразуем в целое, так как Value типа decimal

m = (int)nUDm.Value ;

// Проверка количества элементов FO.

int k=tBFO.Lines.Length;

if ( k!= n+2*m)

{

MessageBox.Show (“Количество элементов FO неверно”);

error=true;

return;

}

//обнуляем матрицу смежности

for(int i = 0; i< n ; i++)

for(int j = 0; j< n ; j++)

MS [i,j]=0;

//Считываем FO и строим матрицу смежности (1.31)

if(!CreatMS(tBFO,ref MS) )

{

error=true;

return;

}

//Контроль симметричности матрицы смежности (1.32)

string msg=””;

if(!SimetrMS(MS,ref msg))

{

MessageBox.Show (msg);

error=true;

return;

}

}

Переходим к проектированию подзадачи (1.4). Расчёт диаметра графа.

int Radius( int[,]MS)

НАЧАЛО

int n =(int)Math.Sqrt(MS.Length) ;

int r=1 ;

int[,] MR=new int[n,n] ;

int[,] B1=new int[n,n]; 

int[,] B2=new int[n,n] ;

bool pr =true;

копировать матрицу MS в MR=MS(1.41)

копировать матрицу MS в В1=MS

ПОКА pr ЦИКЛ

Pr=false;

r=r+1 ;

Умножение матриц В2=В1*MS(1.42)

ДЛЯ i=1 ДО n ЦИКЛ

ДЛЯ j=1 ДО n ЦИКЛ

ЕСЛИ (MR[I,j]=0) и (B2[I,j]<>0 ) ТО

MR[I,j]=r;

Pr=true;

КЕСЛИ

КЦИКЛ

КЦИКЛ

копировать матрицу B2 в В1=B2

КЦИКЛ

Возврат r-1 

КОНЕЦ

Рис. 24

В данном алгоритме есть две подзадачи (рис. 24). Реализуем их.

Подзадача (1.4.1) - копирование матрицы.

CopyMatr(int [,] A ,ref int [,] B)

НАЧАЛО

Int n =(int)Math.Sqrt(A.Length);

ДЛЯ i=1 ДО n ЦИКЛ

ДЛЯ j=1 ДО n ЦИКЛ

B[I,j]=A[I,j];

КЦИКЛ

КЦИКЛ

КОНЕЦ

Подзадача (1.4.2) - умножение матриц С=А*В

MulMatr(int [,] A , int [,] B,ref int[,]C)

НАЧАЛО

int n =(int)Math.Sqrt(A.Length);

int S;

ДЛЯ i=1 ДО n ЦИКЛ

ДЛЯ j=1 ДО n ЦИКЛ

S=0;

ДЛЯkj=1 ДО n ЦИКЛ

S=S+A[I,k]*B[k,j]

КЦИКЛ

C[I,j]=S;

КЦИКЛ

КЦИКЛ

КОНЕЦ

Обе подзадачи запишем на языке C# и подставим в алгоритм (1.4).

public void CopyMatr(int [,] A ,ref int [,] B)

{

iInt n =(int)Math.Sqrt(A.Length);

for(int i=0;i< n; i++)

for(intji=0;j< n; j++)

B[i,j]=A[i,j];

}

public void MulMatr(int [,] A , int [,] B,ref int[,]C)

{

int n =(int)Math.Sqrt(A.Length);

int S;

for(int i=0;i< n; i++)

for(int j=0;j< n; j++)

{

S=0;

for(int k=0;k< n; k++)

S=S+A[i,k]*B[k,j]

C[i,j]=S;

}

}

На рис. 25 отобразим записанные задачи на C#:

Рис. 25

Подставляем задачи в алгоритм (1.4).

int Diametr( int[,]MS)

НАЧАЛО

int n =(int)Math.Sqrt(MS.Length) ;

int r=1 ;

int[,] MR=new int[n,n] ;

int[,] B1=new int[n,n]; 

int[,] B2=new int[n,n] ;

bool pr =true;

//копировать матрицу MS в MR=MS(1.41)

CopyMatr(MS ,ref MR)

// копировать матрицу MS в В1=MS

CopyMatr(MS ,ref B1 )

ПОКА pr ЦИКЛ

pr=false;

r=r+1 ;

// Умножение матриц В2=В1*MS(1.42)

MulMatr(B1 , MS, ref B2)

ДЛЯ i=1 ДО n ЦИКЛ

ДЛЯ j=1 ДО n ЦИКЛ

ЕСЛИ (MR[I,j]=0) и (B2[I,j]<>0 ) ТО

MR[I,j]=r;

Pr=true;

КЕСЛИ

КЦИКЛ

КЦИКЛ

//копировать матрицу B2 в В1=B2

CopyMatr(B2 ,ref B1)

КЦИКЛ

Возврат r-1 ;

КОНЕЦ

Запишем алгоритм на C# и подставим его вместо заглушки (1.4).

public int Diametr( int[,]MS)

{

int n =(int)Math.Sqrt(MS.Length) ;

int r=1 ;

int[,] MR=new int[n,n] ;

int[,] B1=new int[n,n]; 

int[,] B2=new int[n,n] ;

bool pr =true;

//копировать матрицу MS в MR=MS(1.41)

CopyMatr(MS ,ref MR)

// копировать матрицу MS в В1=MS

CopyMatr(MS ,ref B1 )

while ( pr)

{

pr=false;

r=r+1 ;

// Умножение матриц В2=В1*MS(1.42)

MulMatr(B1 , MS, ref B2)

For(int i=0; i< n; i++)

For(int j=0; j< n; j++)

if( (MR[i,j]=0) && (B2[i,j]<>0 ))

{

MR[i,j]=r;

pr=true;

}

//копировать матрицу B2 в В1=B2

CopyMatr(B2 ,ref B1)

}

return r-1

}

Окончательный проект (рис. 26):

Рис. 26