Кузьмина Про-228_РГР. Алгоритмы и структуры данных
Скачать 458.72 Kb.
|
Министерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования «Уфимский государственный авиационный технический университет» Факультет информатики и робототехники Кафедра вычислительной математики и кибернетики Пояснительная записка к расчетно-графической работе по дисциплине «Алгоритмы и структуры данных» Выполнил: Студент группы ПРО-228 Кузьмина Е.В. Проверил: Канд.техн.наук Верхотурова Г.Н. Уфа – 2021 Y 1Постановка задачи 4 1.1.Определение 4 1.1.Входные данные 5 1.2.Промежуточные данные 5 1.3.Описание алгоритма 5 1.4.Код 6 2Примеры работы программы 9 3Список литературы 10 СОДЕРЖАНИЕ Y1 Постановка зада 1.1. Определение 3 1.2. Входные данные 4 1.3. Промежуточные данные 4 1.4. Описание алгоритма 4 1.5. Код 5 2 Примеры работы программы 8 3 Список литературы 9 1Постановка задачи 4 1.1.Определение 4 1.1.Входные данные 5 1.2.Промежуточные данные 5 1.3.Описание алгоритма 5 1.4.Код 6 2Примеры работы программы 9 3Список литературы 10 Постановка задачиНаписать программу нахождения максимального паросочетания для двудольного графа. Разработать алгоритм решения этой задачи и написать программу. ОпределениеОпределение двудольного графа. Двудольный граф - граф, вершины которого можно разбить на два множества так, что каждое ребро соединяет вершины из разных множеств. Определение паросочетания и максимального паросочетания. Паросочетанием M называется набор попарно несмежных рёбер графа (иными словами, любой вершине графа должно быть инцидентно не более одного ребра из множества M). Мощностью паросочетания назовём количество рёбер в нём. Наибольшим (или максимальным) паросочетанием назовём паросочетание, мощность которого максимальна среди всех возможных паросочетаний в данном графе. Описание алгоритма Алгоритм просматривает все вершины v графа: v = 1 … n. Если текущая вершина v уже насыщена текущим паросочетанием (т.е. уже выбрано какое-то смежное ей ребро), то эту вершину пропускаем. Иначе — алгоритм пытается насытить эту вершину, для чего запускается поиск увеличивающей цепи, начинающейся с этой вершины. Поиск увеличивающей цепи осуществляется с помощью специального обхода в глубину. Входные данныеnodes - вершины в графе connections – ребра графа Промежуточные данныеcheckedNodes – просмотренные вершины node – просматриваемая на данный момент вершина Выходные данные: parArray – найденные паросочетания lblAnswer – (элемент Label) поле, в которое выводится найденное максимальное паросочетание В функции FindMaxPar проверяются вершины на просмотренность. Если вершина еще не просмотрена, она просматривается с помощью обхода в глубину. В функции DFS находится такая вершина, которая связана с этой вершиной и при этом еще не просмотрена в функции выше. Найденная вершина отмечается как просмотренная, в массиве parArray отмечается данное паросочетание. Кодusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace RGRAlg { public partial class Form1 : Form { List const int MAXNODES = 25; int[,] connections = new int[MAXNODES, MAXNODES]; int[] checkedNodes = new int[MAXNODES]; int[,] parArray = new int[MAXNODES, MAXNODES]; bool isReadyForCreateNodes = false; int numbersOfNode = 0; int nodeWidth = 30; int nodeHeight = 30; public Form1() { InitializeComponent(); } private void btnCreateNodes_Click(object sender, EventArgs e) { isReadyForCreateNodes = true; } private void btnStopCreateNodes_Click(object sender, EventArgs e) { isReadyForCreateNodes = false; } private void Form1_MouseDown(object sender, MouseEventArgs e) { if (isReadyForCreateNodes) { DrawEllipse(e.X, e.Y); numbersOfNode++; DrawString(numbersOfNode, e.X, e.Y); } } private void DrawEllipse(int x, int y) { System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Black); System.Drawing.Graphics formGraphics; formGraphics = this.CreateGraphics(); Rectangle ellipse = new Rectangle(x - nodeWidth / 2, y - nodeHeight / 2, nodeWidth, nodeHeight); formGraphics.DrawEllipse(myPen, ellipse); nodes.Add(ellipse); myPen.Dispose(); formGraphics.Dispose(); } public void DrawString(int numberOfNode, int xNode, int yNode) { System.Drawing.Graphics formGraphics = this.CreateGraphics(); string drawString = numberOfNode.ToString(); System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 14); System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black); System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat(); formGraphics.DrawString(drawString, drawFont, drawBrush, xNode - nodeWidth / 2, yNode - nodeHeight / 2, drawFormat); drawFont.Dispose(); drawBrush.Dispose(); formGraphics.Dispose(); } private void btnCreateConnect_Click(object sender, EventArgs e) { DrawConnection(nodes[(int)numFirstNode.Value - 1].X + nodeWidth / 2, nodes[(int)numFirstNode.Value - 1].Y + nodeHeight / 2, nodes[(int)numSecondNode.Value - 1].X + nodeWidth / 2, nodes[(int)numSecondNode.Value - 1].Y + nodeHeight / 2); connections[(int)numFirstNode.Value - 1, (int)numSecondNode.Value - 1] = 1; connections[(int)numSecondNode.Value - 1, (int)numFirstNode.Value - 1] = 1; } public void DrawConnection(int x1, int y1, int x2, int y2) { Pen pen = new Pen(System.Drawing.Color.Black); System.Drawing.Graphics formGraphics; formGraphics = this.CreateGraphics(); formGraphics.DrawLine(pen, x1, y1, x2, y2); pen.Dispose(); formGraphics.Dispose(); } void FindMaxPar() { for (int i = 0; i < nodes.Count; i++) { if(checkedNodes[i] == 1) { continue; } else { checkedNodes[i] = 1; DFS(i); } } } void DFS(int node) { for (int j = 0; j < nodes.Count; j++) { if (connections[node, j] == 1 && checkedNodes[j] == 0) { checkedNodes[j] = 1; parArray[node, j] = 1; break; } } } private void btnMaxPar_Click(object sender, EventArgs e) { lblAnswer.Text = ""; for (int i = 0; i < nodes.Count; i++) { for (int j = 0; j < nodes.Count; j++) { parArray[i, j] = 0; } checkedNodes[i] = 0; } FindMaxPar(); for (int i = 0; i < nodes.Count; i++) { for (int j = 0; j < nodes.Count; j++) { if (parArray[i, j] != 0) { lblAnswer.Text += (i + 1) + " и " + (j + 1) + " "; } } } } } } Оценка сложности: Алгоритм можно представить, как серию из n запусков обхода в глубину на всём графе. Следовательно, всего этот алгоритм исполняется за время O (n m), что в худшем случае есть O (n^2). Примеры работы программыСписок литературыMetanit.com — сайт о программировании [Электронный ресурс]. URL: https://metanit.com/sharp/adonet/3.5.php Stack Overflow — сайт вопросов и ответов для программистов [Электронный ресурс]. URL: https://ru.stackoverflow.com CyberForum.ru — веб-форум для IT-специалистов [Электронный ресурс]. URL: https://www.cyberforum.ru |