- •Малюнок 1.1 – Неорієнтований граф
- •1.1. Способи представлення графів в пам'яті еом
- •Постановка задачі
- •Вхідні данні
- •Малюнок 2 – Вхідна форма
- •Малюнок 3 – Складова текстового файла
- •Малюнок 4 – Вхідні форми
- •Аномалії
- •Функціональні тести
- •Нисхідна проектування
- •Зрівняння графів на еквівалентность
- •Лістинг:
- •Тестові приклади:
- •Література
Зрівняння графів на еквівалентность
1.3
1.2
1.4
1.1
1.2.1
1.3.1
1.4.1
Введення графа з файлу з частковим контролем (функція Input_graf_screen (…));
Побудова матриці інцидентності (функція form_graf (…));
Преобразовиваніе вектора в матрицю інцидентності (функция from_vec_to_matrix (…));
Видалення весящих вершин (…);
Знаходження діаметра для другого графа;
Функція виведення даних на головну форму (…);
Функція виведення даних на головну форму 2 (…).
Лістинг:
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Kursovoi_Proect
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
StreamReader SRead = null;
int[][] MI1 = new int[0][];
int[][] MI2 = new int[0][];
string FI1, FI2;
int N1, M1, N2, M2, num_graf;
private void TB_FI_first_KeyPress(object sender, KeyPressEventArgs e)
{
if (!((char.IsControl(e.KeyChar)) || (char.IsDigit(e.KeyChar)) || (char.IsWhiteSpace(e.KeyChar))))
e.KeyChar = '\0';
}
//функция чтения графа
static void Input_graf_screen(OpenFileDialog OpFlDl, CheckBox ChBx, StreamReader SR, ref string FI, ref int N, ref int M, int n_g)
{
if (OpFlDl.ShowDialog() == DialogResult.OK)
{
string fullname = OpFlDl.FileName;
int pos = fullname.LastIndexOf("\\");
string shortname = fullname.Substring(pos + 1);
//MessageBox.Show("Открыт файл с именем \n" + shortname);
SR = new StreamReader(fullname);
string help_str;
help_str = SR.ReadLine();
string[] N_M = help_str.Split(' ');
N = int.Parse(N_M[0]);
if ((N < 1) || (N > 20))
throw new
DivideByZeroException("Недопустимое количество вершин " + n_g.ToString() + "-го графа");
M = int.Parse(N_M[1]);
if ((M < 0) || (M > 50))
throw new
DivideByZeroException("Недопустимое количество рёбер" + n_g.ToString() + "-го графа");
string s;
help_str = SR.ReadLine();
while ((s = SR.ReadLine()) != null)
help_str += " " + s;
SR.Close();
FI = help_str;
}
}
//функция возвращает сформированую матрицу инцидентности
static void form_graf(string k, ref int[][] A, int n, int m, int n_gr)
{
int zero = 1;
string[] chisla = k.Split(' ');
int[] chislo = new int[chisla.Length];
for (int i = 0; i < chisla.Length; i++)
{
chislo[i] = int.Parse(chisla[i]);
if ((chislo[i] < 0) || (chislo[i] > n))
throw new
DivideByZeroException("Элемент вектора FI" + n_gr.ToString() + " вне диапазона");
}
if (chislo.Length > (2 * m + n))
throw new
DivideByZeroException("Количество элементов вектора FI" + n_gr.ToString() + " должно быть меньше");
if (chislo.Length < (2 * m + n))
throw new
DivideByZeroException("Количество элементов вектора FI" + n_gr.ToString() + " должно быть больше");
for (int i = 0; i < chislo.Length; i++)
if (chislo[i] == 0)
zero++;
Array.Resize(ref A, zero);
for (int i = 0; i < zero; i++)
Array.Resize(ref A[i], zero);
from_vec_to_matrix(chislo, ref A);
for (int i = 0; i < A.Length; i++)
for (int j = 0; j < A.Length; j++)
if (A[i][j] != A[j][i])
throw new
DivideByZeroException("Матрица инцидентности графа №" + n_gr.ToString() + " не симметричная.\n" + "Неориентированный граф задан неверно");
}
//функция формирует из вектора, который задает граф, матрицу инцидентности
static void from_vec_to_matrix(int[] vec, ref int[][] mat)
{
int S = 0;
int p0 = 0;
for (int i = 0; i < vec.Length; i++)
{
if (vec[i] == 0)
{
p0 += S;
S = 0;
}
else
{
mat[i - S - p0][vec[i] - 1] = 1;
S++;
}
}
}
public void Max_strong_subset(int sizer, int[][]MI1, ref int k)
{
int[] vrem = new int[sizer];
int[] G = new int[sizer];
int[] G_ = new int[sizer];
int[] temp = new int[sizer];
try
{
int start_top = 1;
for (int i = 0; i < sizer; i++)
{
vrem[i] = 1;
}
vrem[start_top] = 0;
General_function(start_top, sizer, ref G, ref G_, ref temp, ref MI1, k, ref vrem);
for (int i = 0; i < sizer; i++)
{
if (vrem[i] == 1)
{
General_function(i, sizer, ref G, ref G_, ref temp, ref MI1, k, ref vrem);
k++;
}
}
}
catch (Exception)
{
MessageBox.Show("Введите номер cуществующей вершины!", "Error!");
}
}
public void General_function(int ver, int sizer, ref int[] G, ref int[] G_, ref int[] temp, ref int[][] MI1, int k, ref int[] vrem)
{
int v = ver;
for (int i = 0; i < sizer; i++)
{
G[i] = 0;
G_[i] = 0;
temp[i] = -1;
}
bool tr = true;
G[v] = 1;
temp[v] = 1;
for (int j = 0; j < sizer; j++)
{
if (MI1[v][j] == 1)
{
G[j] = 1;
if (temp[j] == -1)
{
temp[j] = 1;
}
}
if (!(j + 1 < sizer))
{
for (int i = 0; i < sizer && tr; i++)
{
if (temp[i] == 1)
{
temp[i] = 0;
j = -1;
v = i;
tr = false;
}
}
tr = true;
}
}
for (int i = 0; i < sizer; i++)
{
temp[i] = -1;
}
v = ver;
G_[v] = 1;
temp[v] = 1;
for (int j = 0; j < sizer; j++)
{
if (MI1[j][v] == 1)
{
G_[j] = 1;
if (temp[j] == -1)
{
temp[j] = 1;
}
}
if (!(j + 1 < sizer))
{
for (int i = 0; i < sizer && tr; i++)
{
if (temp[i] == 1)
{
temp[i] = 0;
j = -1;
v = i;
tr = false;
}
}
tr = true;
}
}
for (int i = 0; i < sizer; i++)
{
if (G_[i] == G[i] && G[i] == 1)
{
vrem[i] = 0;
}
}
}
public void Max_strong_subset2(int sizer, int[][] MI2, ref int k2)
{
int[] vrem = new int[sizer];
int[] G = new int[sizer];
int[] G_ = new int[sizer];
int[] temp = new int[sizer];
try
{
int start_top = 1;
for (int i = 0; i < sizer; i++)
{
vrem[i] = 1;
}
vrem[start_top] = 0;
General_function2(start_top, sizer, ref G, ref G_, ref temp, ref MI2, k2, ref vrem);
for (int i = 0; i < sizer; i++)
{
if (vrem[i] == 1)
{
General_function2(i, sizer, ref G, ref G_, ref temp, ref MI2, k2, ref vrem);
k2++;
}
}
}
catch (Exception)
{
MessageBox.Show("Введите номер cуществующей вершины!", "Error!");
}
}
public void General_function2(int ver, int sizer, ref int[] G, ref int[] G_, ref int[] temp, ref int[][] MI2, int k2, ref int[] vrem)
{
int v = ver;
for (int i = 0; i < sizer; i++)
{
G[i] = 0;
G_[i] = 0;
temp[i] = -1;
}
bool tr = true;
G[v] = 1;
temp[v] = 1;
for (int j = 0; j < sizer; j++)
{
if (MI2[v][j] == 1)
{
G[j] = 1;
if (temp[j] == -1)
{
temp[j] = 1;
}
}
if (!(j + 1 < sizer))
{
for (int i = 0; i < sizer && tr; i++)
{
if (temp[i] == 1)
{
temp[i] = 0;
j = -1;
v = i;
tr = false;
}
}
tr = true;
}
}
for (int i = 0; i < sizer; i++)
{
temp[i] = -1;
}
v = ver;
G_[v] = 1;
temp[v] = 1;
for (int j = 0; j < sizer; j++)
{
if (MI2[j][v] == 1)
{
G_[j] = 1;
if (temp[j] == -1)
{
temp[j] = 1;
}
}
if (!(j + 1 < sizer))
{
for (int i = 0; i < sizer && tr; i++)
{
if (temp[i] == 1)
{
temp[i] = 0;
j = -1;
v = i;
tr = false;
}
}
tr = true;
}
}
for (int i = 0; i < sizer; i++)
{
if (G_[i] == G[i] && G[i] == 1)
{
vrem[i] = 0;
}
}
}
private void fdhghToolStripMenuItem_Click(object sender, EventArgs e)
{
string info = "Используя технологию нисходящего проектирования сравнить два неориентированных графа представленных массивом предшественников (Fi – представления) на эквивалентность по характеристике: Диаметр графа после удаления в нем висячих вершин. Вершин графа не боле 20, число ребер не более 50.Предусмотреть ввод данных с клавиатуры и с текстового файла.Разработать программу в виде выполняемого файла для решения задачи различения двух файлов.";
MessageBox.Show(info, "О программе", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void сравнитьToolStripMenuItem_Click(object sender, EventArgs e)
{
MI1 = new int[0][];
MI2 = new int[0][];
FI1 = "";
FI2 = "";
N1 = M1 = N2 = M2 = num_graf = 0;
int k = 1;
int k2 = 1;
try
{
//чтение первого графа
if (ChBx_first.Checked == true)
{
num_graf = 1;
MessageBox.Show("Выбирите файл, в котором задан первый граф");
Input_graf_screen(OpenFlDl, ChBx_first, SRead, ref FI1, ref N1, ref M1, num_graf);
}
if (checkBox1.Checked == true)
{
FI1 = TB_FI_first.Text;
N1 = int.Parse(num_top_first.Value.ToString());
M1 = int.Parse(num_edge_first.Value.ToString());
}
//чтение второго графа
if (ChBx_first.Checked == true)
{
num_graf = 2;
MessageBox.Show("Выбирите файл, в котором задан второй граф");
Input_graf_screen(OpenFlDl, ChBx_first, SRead, ref FI2, ref N2, ref M2, num_graf);
}
if (checkBox1.Checked == true)
{
FI2 = TB_FI_second.Text;
N2 = int.Parse(num_top_second.Value.ToString());
M2 = int.Parse(num_edge_second.Value.ToString());
}
//обрабатываем первый граф
num_graf = 1;
form_graf(FI1, ref MI1, N1, M1, num_graf);
if (MI1.Length < 2)
throw new
DivideByZeroException("Первый граф превратился в точку");
else
Max_strong_subset(N1, MI1, ref k);
textBox1.Text = "Диамерт графа равен: " + k; ;
//обрабатываем второй граф
num_graf = 2;
form_graf(FI2, ref MI2, N2, M2, num_graf);
if (MI2.Length < 2)
throw new
DivideByZeroException("Второй граф превратился в точку");
else
Max_strong_subset2(N2, MI2, ref k2);
textBox2.Text = "Диаметр графа равен: " + k2;
//сравнивание количества центральных вершин первого и второго графов
if (k == k2)
MessageBox.Show("Данные графы эквивалентны!", "Результат");
else
MessageBox.Show("Данные графы не эквивалентны!", "Результат");
}
catch (FormatException)
{
MessageBox.Show("Введены недопустимые символы! Допустим только один пробел между цифрами!", "Ошибка!");
}
catch (DivideByZeroException x)
{
MessageBox.Show(x.Message, "Ошибка!");
}
}
private void выходToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
private void label9_Click(object sender, EventArgs e)
{
}
private void очисститьПоляToolStripMenuItem_Click(object sender, EventArgs e)
{
TB_FI_first.Clear();
textBox1.Clear();
TB_FI_second.Clear();
textBox2.Clear();
}
}
}
