- •Общие положения
- •Цель и задачи курсовой работы
- •Порядок выполнения
- •Требования к оформлению пояснительной записки
- •Краткие теоретические сведения
- •Основные определения теории графов
- •Способы представления графов в памяти эвм
- •Матрица смежностей графа
- •Матрица инцидентностей графа
- •Задание графа массивом преемников вершин (fo-представление графа)
- •Задание графа массивом предшественником вершин (fi-представление)
- •Модифицированное fo-представление графа (mfo-представление)
- •Модифицированное fi-представление графа (mfi-представление)
- •Сокращенные mfо и mfi-представления неорграфов
- •Нисходящее проектирование
- •Технология проектирования алгоритмов
- •Принципы нисходящего проектирования:
- •Варианты заданий для курсовой работы
- •Варианты расчетных заданий
- •Организация защиты курсовой работы
- •Постановка задачи
- •Входные данные
- •Аномалии
- •Функциональные тесты
- •Нисходящее проектирование
- •Основной алгоритм
- •Нисходящее проектирование на класcах
- •Методы public Kurs_Proekt ()
- •Библиографический список
- •Содержание
Нисходящее проектирование
Основной алгоритм
АЛГОРИТМ Курсовой_проект
<Описание переменных> (см. спецификацию)
НАЧАЛО
ЕСЛИ (ввод с файла) ТО
Выбор файла и создание потока(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