Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49

Реализация графов своим классом и DFS

29.04.2019, 22:45. Показов 3376. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
В вузе я получил вот такое задание:

Создать класс в соответствии с вариантом, реализующий граф:
1)В качестве внутреннего представления графа использовать метод список ребер
2)В качестве входного параметра передавать граф в формате матрицы смежности
3)Реализовать алгоритм обработки графа - проверка на наличие циклов в графе
4) Создать проект для автоматизации тестирования и создать набор тестов для проверки работы класса

У меня возникли вопросы с пониманием задания:
1)"качестве внутреннего представления графа использовать метод список ребер" - это значит что реализуемый мной класс получает на вход граф в каком -то виде и преобразует его в список ребер? И этот список ребер должен быть реализован как двумерный массив или как совокупность листа вершин и листа ребер?

2)Я реализовал класс Graf как двумерны массив, но я не знаю "правильно" ли это? Может стоит изменить реализацию?

2)"В качестве входного параметра передавать граф в формате матрицы смежности" - я исхожу из того что передавать граф нужно на вход алгоритма обработки графа (а именно проверка на наличие циклов в графе) если это неправильное предположение поправьте меня пожалуйста, это значит что перед передачей моего объекта класса Graf я должен преобразовать его в объект класса Array[,] или же преобразования объекта передаваемого в алгоритм обработки графа (DFS) должны быть сделаны внутри самого класса Graf?

3)В данный момент я реализовал проверку на наличие циклов в графе как static void DFS(int [,] MatricaSmegnosti, int[] Colors, int BeginVertex, int predok = -1)
Т.е. функция DFS принимает на вход двумерный массив, но не может принимать объекты класса Graf.
- И как мне поступить? Переделать DFS так чтобы он принимал на вход объекты класса Graf (но не принимал объекты класса Array[,]) или же наоборот как-то переделать свой класс Graf чтобы он полностью соответствовал требованиям класса Array[,]?

Все это я пытаюсь реализовать на C#
Вот код проекта целиком:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
 
namespace ConsoleApplicationАиСД_Л2
{
    //1) Создать класс в соответствии с вариантом, реализующий граф.
    //2) В качестве внутреннего представления графа использовать метод Список ребер
    //3) В качестве входного параметра передавать представление графа - Матрица смежности
    //передавать куда??? в DFS?
    //4) Реализовать алгоритм обработки графа - проверку на наличие циклов в графе [ g.Dfs(); ? ]
    //5) Создать проект для автоматизации тестирования и создать набор тестов для проверки работы класса
 
 
    class Graf  //класс не может быть производным от Array?
    {
        //int[,] Graf = new int[,];
 
        public Graf(int[,] MatricaSmegnosti)                    //конструктор класса Graf
        {
            int kolichectvo_reber = ribs(MatricaSmegnosti, 0); //вычисление количества ребер в формате СПИСОК РЕБЕР //я не разобрался до конца
            int a = kolichectvo_reber, b = 2, n = (MatricaSmegnosti.GetLength(0)); //b - количество столбцов в матрице СПИСКА РЕБЕР
                                                                                   //n - количество строк в матрице смежности(нужно для парсера)
            int[,] Graf = new int[a,b];                                            //объявление графа,CP реализованого как массив int[,]
 
            //блок первода графа из формата МС в СР
            int l = 0, k = 0;                                                       //костыль для парсера
            for (int i = 0; i < n; i++)                                             //найти правильную реализацию парсера
            {                                   //этот способ парсинга при каждом
                for (int j = i; j < n; j++)     //проходе цикла исключатет пройденую
                {                               //строку и соответственно пройденый столбец
                    if (MatricaSmegnosti[i, j] == 1)//исключая таким образом уже пройденые варианты
                    {
                        Graf[k, l] = i + 1;                                         //запись первой инциндентной ребру вершины в массив СР[*,]
                        Graf[k, l + 1] = j + 1;                                     //запись второй инциндентной ребру вершины в массив СР[,*]
                        k++;                                                        //счетчик "как-бы цыкла"
                    }
                }
            }
            //блок первода графа из формата МС в СР
 
            Console.WriteLine("Граф (список ребер):");
            for (int i = 0; i < a; i++) //(Вывод графа)
            {
                for (int j = 0; j < b; j++)
                {
                    Console.Write(" " + Graf[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
 
        public Graf(int[,] SpisokReber, int Eges)                    //конструктор2 класса Graf
        {                                                            //SpisokReber счет от 0
            int v = vertexes(SpisokReber, Eges);                    //получение кол-ва вершин, счет начинается с 0, а не с 1
            int[,] Graf = new int[v,v];                             //объявление графа,МС реализованого как массив int[,]
 
            Console.WriteLine("v = " + v);
 
            for (int i = 0; i < Eges; i++)                          //перевод графа из СР в МС
            {
                Graf[SpisokReber[i,0], SpisokReber[i,1]] = 1;
                Graf[SpisokReber[i, 1], SpisokReber[i, 0]] = 1;
            }
 
            /*for (int i = 0; i < v; i++)                             //вывод графа (в МС)
            {
                for (int j = 0; j < v; j++)
                {
                    Console.Write(" " + Graf[i, j] + " ");
                }
                Console.WriteLine();
            }*/
        }
 
        static int vertexes(int[,] SpisokReber, int Eges)
        {
            int max = 0;
            for (int i = 0; i < Eges; i++)
            {
                for (int j = 0; j < SpisokReber.GetLength(1); j++)
                {
                    if (max < SpisokReber[i,j]) max = SpisokReber[i,j];
                }
            }
            return max+1;
        }
 
        //вычисление количества ребер(по размерности МС) для будущево графа в формате СР
        static int ribs(int[,] m, int a)
        {
            a = 0;
            for (var j = 0; j < m.GetLength(0); j++)
            {
                for (var i = 0; i <= j; i++)
                {
                    if (m[i, j] == 1) a++;
                }
            }
            return a;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            string buf;
            char TaskNumber;
            const int m = 7, n = 7;
            int[,] MatricaSmegnosti = new int[m, n];
            int[] Colors;
 
 
            Console.WriteLine("1 - Задание графа с помощю МС \n2 - Задание графа с помощю СР \n");
            Console.WriteLine("Введите номер задачи:");
            buf = Console.ReadLine();
            TaskNumber = Char.Parse(buf);
            Console.WriteLine("Выбрана задача: " + TaskNumber);
 
            switch (TaskNumber)
            {
            case '1':
            {
            MatricaSmegnosti = new int[m, n] { //матрица смежности для передачи в качестве входного параметра
            { 0, 0, 0, 1, 1, 0, 0 }, 
            { 0, 0, 1, 0, 1, 1, 0 },
            { 0, 1, 0, 0, 0, 0, 0 },
            { 1, 0, 0, 0, 0, 1, 1 },
            { 1, 1, 0, 0, 0, 0, 1 },
            { 0, 1, 0, 1, 0, 0, 1 },
            { 0, 0, 0, 1, 1, 1, 0 }
            };
            Console.WriteLine("Матрица смежности:");
            Console.WriteLine("Размерность матрицы смежности = " + MatricaSmegnosti.GetLength(0));
 
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write(" " + MatricaSmegnosti[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
 
            Graf Alpha = new Graf(MatricaSmegnosti);//создание обекта класса Graf (тупо перевод в СР)
                        }break;
            case '2':
            {
                Console.WriteLine("Введите количество ребер графа:");
                int Eges = Convert.ToInt32(Console.ReadLine());
                string[] MASstr1;
                int[,] SpisokReber = new int[Eges, 2];
                Console.WriteLine("Введите вершины графа V1 и V2 через пробел:");
                for(int i=0; i< Eges; i++)
                {
                Console.WriteLine("V1 V2");
                string str = Console.ReadLine();
                MASstr1 = str.Split(' ');
                for (int j = 0; j < (MASstr1.Length); j++)
                {
                    SpisokReber[i, j] = (Convert.ToInt32(MASstr1[j]) - 1);
                }
 
                }
                Console.WriteLine("Граф в формате СР:");
                for (int i = 0; i < Eges; i++) //(Вывод графа)
                {
                    for (int j = 0; j < 2; j++)
                    {
                        Console.Write(" " + SpisokReber[i, j] + " ");
                    }
                    Console.WriteLine();
                }
 
                Graf Alpha = new Graf(SpisokReber, Eges);
                //для моего класса граф не определен метод GetLength
                /*
                Colors = new int[Alpha.GetLength(0)];
                for (int i = 0; i < Alpha.GetLength(0); i++)
                {
                    Colors[i] = 1;
                }
                DFS(Alpha, Colors, 0);
                */
              
            }break;
 
            }
 
            Colors = new int[MatricaSmegnosti.GetLength(0)];
            for (int i = 0; i < MatricaSmegnosti.GetLength(0); i++)
            {
                //for (int j = 0; j < MatricaSmegnosti.GetLength(0); j++) //нужная ли строка?
                    Colors[i] = 1;
            }
            DFS(MatricaSmegnosti, Colors, 0);
        }
 
        static void DFS(int [,] MatricaSmegnosti, int[] Colors, int BeginVertex, int predok = -1)
        {
                Colors[BeginVertex] = 2;
 
                for (int i = 0; i < MatricaSmegnosti.GetLength(0); i++)
                {
                    if (MatricaSmegnosti[BeginVertex, i] == 1 && Colors[i] == 1)
                    {
                        DFS(MatricaSmegnosti, Colors, i, BeginVertex);
                    }
                    else if (i != predok && MatricaSmegnosti[BeginVertex, i] == 1 && Colors[i] == 2)//==2
                    {
                        Console.WriteLine("Граф имеет цикл");
                        Console.WriteLine("начало цикла = {0}, конец = {1}", BeginVertex, i);
 
                    }
                }
                Colors[BeginVertex] = 3;
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.04.2019, 22:45
Ответы с готовыми решениями:

Управление своим классом
Есть у меня свой главный/общий класс Ship. Представляет из себя PictureBox и различные методы управления этим PictureBox. Унаследовал...

Использование priority_queue со своим классом
Если в классе перегрузить оператор '&gt;', то можно использовать такую конструкцию? priority_queue &lt;Class, vector &lt;Class&gt;, greater...

Захламление памяти своим классом
Всем здрасьте! У меня такой вопрос. Есть класс MExecTableSQL(&lt;table&gt;,&lt;SQL&gt;, &lt;int&gt;), с которым при, грубо говоря, нажатии на разные кнопки...

16
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
30.04.2019, 12:51
Цитата Сообщение от ВящЕ Посмотреть сообщение
1)"качестве внутреннего представления графа использовать метод список ребер" - это значит что реализуемый мной класс получает на вход граф в каком -то виде и преобразует его в список ребер? И этот список ребер должен быть реализован как двумерный массив или как совокупность листа вершин и листа ребер?
список рёбер

Цитата Сообщение от ВящЕ Посмотреть сообщение
2)"В качестве входного параметра передавать граф в формате матрицы смежности" - я исхожу из того что передавать граф нужно на вход алгоритма обработки графа (а именно проверка на наличие циклов в графе) если это неправильное предположение поправьте меня пожалуйста, это значит что перед передачей моего объекта класса Graf я должен преобразовать его в объект класса Array[,] или же преобразования объекта передаваемого в алгоритм обработки графа (DFS) должны быть сделаны внутри самого класса Graf?
конструктор

Цитата Сообщение от ВящЕ Посмотреть сообщение
3)В данный момент я реализовал проверку на наличие циклов в графе как static void DFS(int [,] MatricaSmegnosti, int[] Colors, int BeginVertex, int predok = -1)
Т.е. функция DFS принимает на вход двумерный массив, но не может принимать объекты класса Graf.
- И как мне поступить? Переделать DFS так чтобы он принимал на вход объекты класса Graf (но не принимал объекты класса Array[,]) или же наоборот как-то переделать свой класс Graf чтобы он полностью соответствовал требованиям класса Array[,]?
метод класса

Цитата Сообщение от ВящЕ Посмотреть сообщение
kolichectvo_reber
Переменные принято называть на английском языке.
1
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
30.04.2019, 13:40
Shamil1,
Цитата Сообщение от ВящЕ Посмотреть сообщение
1)"качестве внутреннего представления графа использовать метод список ребер" - это значит что реализуемый мной класс получает на вход граф в каком -то виде и преобразует его в список ребер? И этот список ребер должен быть реализован как двумерный массив или как совокупность листа вершин и листа ребер?
совокупность списка вершин и списка рёбер. То есть ты должен читать матрицу, но сохранять не её, а список из рёбер.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      
Console.WriteLine("Введите матрицу смежности:");      
for (int i = 0; i < m; i++)
            {
 
                string str = Console.ReadLine();
                MASstr1 = str.Split(' ');
                for (int j = 0; j < n; j++)
                {  
                         //MatricaSmegnosti[i, j] = и тут можно даже переменную MatricaSmegnosti[] не создавать
//а сразу конвертировать номер матрицы в список рёбер.
                         if (MASstr1[j]!=0) 
                         {
                         SpisokReber[].Add({i, j});
                         }
                }
1
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
30.04.2019, 14:47
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
совокупность списка вершин и списка рёбер
В задании написано "метод список ребер". Этот метод не предусматривает хранение списка вершин (несвязанные вершины пропадают).
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
01.05.2019, 20:04  [ТС]


Рисунок это список ребер и сам граф.

Цитата Сообщение от Shamil1 Посмотреть сообщение
список рёбер
1)Т.е. мой класс должен реализовать граф как: 1)Двумерный массив, или 2)Одномерный массив, или 3)Список элементов, или 4)Список двумерных массивов?

Цитата Сообщение от Shamil1 Посмотреть сообщение
конструктор
2)Т.е. для передачи графа куда-либо нужно добавить в класс отдельный конструктор? Но я не могу создать объект вида Graf[,]
что должен создавать конструктор?

3)Чтобы получить размерность обекта класса граф нужно написать собственный метод получения размерности?
C#
1
2
3
4
public int Length
        {
            get { return lenght; }
        }
А для доступа к элементам обекта по индексу [,] нужно написать индексатор?
Или можно обойтись без собственных методов?
0
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
02.05.2019, 13:33
Цитата Сообщение от ВящЕ Посмотреть сообщение
1)Т.е. мой класс должен реализовать граф как: 1)Двумерный массив, или 2)Одномерный массив, или 3)Список элементов, или 4)Список двумерных массивов?
Между списком и массивом нет принципиальной разницы. Я бы использовал список.
Для элементов списка Вы можете создать структуру "ребро" с двумя свойствами "из" и "в", а можете использовать кортеж. Я бы создал структуру.

Цитата Сообщение от ВящЕ Посмотреть сообщение
2)Т.е. для передачи графа куда-либо нужно добавить в класс отдельный конструктор?
Нет. Вы передаёте экземпляр класса "граф".
Один из конструкторов этого класса принимает параметр "матрица смежности" типа двумерный массив и заполняет приватное поле "список рёбер".

Цитата Сообщение от ВящЕ Посмотреть сообщение
3)Чтобы получить размерность обекта класса граф нужно написать собственный метод получения размерности?
Я не знаю, что такое "размерность графа". Если Вам зачем-то нужно, то Вы можете добавить свойства, возвращающие количество вершин или количество рёбер.
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
02.05.2019, 15:21  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Нет. Вы передаёте экземпляр класса "граф".
Один из конструкторов этого класса принимает параметр "матрица смежности" типа двумерный массив и заполняет приватное поле "список рёбер".
Т.е. я создаю объект класса граф в конструкторе:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public Graf(int[,] MatricaSmegnosti)                    //третий конструктор класса Graf
        {
            int kolichectvo_reber = ribs(MatricaSmegnosti, 0); //вычисление количества ребер в формате СПИСОК РЕБЕР //я не разобрался до конца
            int a = kolichectvo_reber, b = 2, n = (MatricaSmegnosti.GetLength(0)); //b - количество столбцов в матрице СПИСКА РЕБЕР
                                                                                    //n - количество строк в матрице смежности(нужно для парсера)
            SR = new int[a, b];                                                     //выдиление памяти для CP реализованого как массив int[,]
 
            //блок первода графа из формата МС в СР
            int l = 0, k = 0;                                                       //костыль для парсера
            for (int i = 0; i < n; i++)                                             //найти правильную реализацию парсера
            {                                   //этот способ парсинга при каждом
                for (int j = i; j < n; j++)     //проходе цикла исключатет пройденую
                {                               //строку и соответственно пройденый столбец
                    if (MatricaSmegnosti[i, j] == 1)//исключая таким образом уже пройденые варианты
                    {
                        SR[k, l] = i + 1;                                         //запись первой инциндентной ребру вершины в массив СР[*,]
                        SR[k, l + 1] = j + 1;                                     //запись второй инциндентной ребру вершины в массив СР[,*]
                        k++;                                                        //счетчик "как-бы цыкла"
                    }
                }
            }
            //блок первода графа из формата МС в СР.
 
            Console.WriteLine("Граф (список ребер):");
            for (int i = 0; i < a; i++) //(Вывод графа)
            {
                for (int j = 0; j < b; j++)
                {
                    Console.Write(" " + SR[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
       
 
        public int GetSR(int i,int j)                           //получение значения элемента двумерного массива
        { return SR[i,j]; }                                     //по идексу обратится не получилось
 
        private int[,] SR;                                      //закрытое поле массив int[,]
 
        public int GetLenght()                                  //метод получения размерности масива
        { return (SR.GetLength(0)); }
А для доступа к приватному полю СписокРебер реализованному, допустим, как двумерный массив int[вершина1,вершина2] я осуществлю по методам:

1) Для получения значения конкретного элемента массива:
C#
1
2
public int GetSR(int i,int j)                           //получение значения элемента двумерного массива
        { return SR[i,j]; }                                     //по идексу обратится не получилось
2) Для получения размерности этого массива:
C#
1
2
public int GetLenght()                                  //метод получения размерности масива
        { return (SR.GetLength(0)); }
И соответственно сам DFS:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        static void DFS2(Graf Graf, int[] Colors, int BeginVertex, int predok = -1)
        {
            Colors[BeginVertex] = 2;
 
            for (int i = 0; i < Graf.GetLenght(); i++)
            {
                if (Graf.GetSR(BeginVertex, i) == 1 && Colors[i] == 1)
                {
                    DFS2(Graf, Colors, i, BeginVertex);
                }
                else if (i != predok && Graf.GetSR(BeginVertex, i) == 1 && Colors[i] == 2)//==2
                {
                    Console.WriteLine("Граф имеет цикл");
                    Console.WriteLine("начало цикла = {0}, конец = {1}", BeginVertex, i);
 
                }
            }
            Colors[BeginVertex] = 3;
        }

Самое главное что по заданию мне нужно реализовать граф как список ребер, а передавать в DFS его нужно как матрицу смежности и меня это запутывает. Т.е. нужно делать преобразование графа из формата матрица смежности (а в задании вообще не указано в каком формате нужно вводить граф) -> в формат список ребер (просто для создания объекта класса) -> а потом обратно в матрицу смежности для обработке графа в DFS.
Или я неправельно понял задание.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
02.05.2019, 16:37
Цитата Сообщение от ВящЕ Посмотреть сообщение
а передавать в DFS его нужно как матрицу смежности
что-то я не вижу, чтобы по заданию говорилось передавать в DFS непременно матрицу смежности и ни в коем случае не список рёбер.

DFS это всего лишь алгоритм, его легко переписать и для списка рёбер.
0
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
03.05.2019, 12:11
Так:
C#
1
2
    List<ValueTuple<int,int>> edges = new List<ValueTuple<int,int>>();
    edges.Add((i,j));
Либо так:
C#
1
2
    List<Edge> edges = new List<Edge>();
    edges.Add(new Edge(i, j));
Добавлено через 5 минут
Цитата Сообщение от ВящЕ Посмотреть сообщение
SR = new int[a, b];
Список рёбер не может быть двумерным массивом. Если массив, то одномерный массив, элементами которого являются рёбра.
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
03.05.2019, 14:39  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Так:
C#
1
2
List<ValueTuple<int,int>> edges = new List<ValueTuple<int,int>>();
 edges.Add((i,j));
Либо так:
C#
1
2
List<Edge> edges = new List<Edge>();
 edges.Add(new Edge(i, j));
C#
1
 
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        public Graf(int[,] MatricaSmegnosti)                    //третий конструктор класса Graf
        {
            List<Edge> edges = new List<Edge>();                //обявление CP реализованого как список объектов Edge                      
 
            int kolichectvo_reber = ribs(MatricaSmegnosti, 0); //вычисление количества ребер в формате СПИСОК РЕБЕР //я не разобрался до конца
            int a = kolichectvo_reber, n = (MatricaSmegnosti.GetLength(0)); //b - количество столбцов в матрице СПИСКА РЕБЕР
                                                                            //n - количество строк в матрице смежности(нужно для парсера)
 
            //блок первода графа из формата МС в СР
            for (int i = 0; i < n; i++)
            {                                       //этот способ парсинга при каждом
                for (int j = i; j < n; j++)         //проходе цикла исключатет пройденую
                {                                   //строку и соответственно пройденый столбец
                    if (MatricaSmegnosti[i, j] == 1)//исключая таким образом уже пройденые варианты
                    {
                        edges.Add(new Edge((i + 1), (j + 1)));  //т.к. элементы в масиве нумеруется начиная с 0 а не с 1 добавляю 1
                    }
                }
            }
            //блок первода графа из формата МС в СР.
 
            Console.WriteLine("edges.Count = " + edges.Count);
            Console.WriteLine("Граф (список ребер):");
            Console.WriteLine();
            foreach (Edge Edge in edges)
            {
                Console.WriteLine(Edge.v0 + " " + Edge.v1);
            }
        }
 
        class Edge
        {
            //номера вершин
            public int v0;
            public int v1;
 
 
            public Edge(int v0, int v1)
            {
                this.v0 = v0;
                this.v1 = v1;
            }
        }
Так?

Добавлено через 57 минут
Подскажите как получать доступ к списку ребер объекта класса Graf?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace ConsoleApplicationАиСД_Л2
{
    class Graf //класс не может быть производным от Array?
   {
   public Graf(int[,] MatricaSmegnosti)                    //третий конструктор класса Graf
   {}
   List<Edge> edges = new List<Edge>();
    }
class Program
    {
    static void Main(string[] args)
    {
       Alpha = new Graf(MatricaSmegnosti);//создание обекта класса Graf
       здесь нужно обрабатывать список ребер который реализован как поле класа граф
}
0
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
03.05.2019, 18:03
Цитата Сообщение от ВящЕ Посмотреть сообщение
Так?
Да. Только лучше Edge сделать структурой, так как по сути это велью тип.
C#
1
2
3
4
5
6
7
8
9
10
11
public struct Edge
{
    public int From { get; }
    public int To { get; }
    
    public Edge(int from, int to)
    {
        From = from;
        To = to;
    }
}
Цитата Сообщение от ВящЕ Посмотреть сообщение
Подскажите как получать доступ к списку ребер объекта класса Graf?
C#
1
public List<Edge> Edges { get; }
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
03.05.2019, 19:31  [ТС]
Что-то у меня не получилось реализовать доступ через метод класса public List<Edge> edges { get; }
компилятор пишет что еще должен быть определен set, если тупо добавить set то всеравно нето.
и кстати если:
C#
1
2
3
List<Edge> edges = new List<Edge>();  - поле класа
и 
public List<Edge> edges { get;  }           - метод
компилятор почему-то считает этот метод определением этой переменной edges

Вобщем пока пеализовал поле класса как публичное:
C#
1
2
3
4
class Graf
{
public List<Edge> edges = new List<Edge>(); 
}
а сам доступ к списку ребер получаю вот так:
C#
1
2
3
4
 foreach (Graf.Edge Edge in Alpha.edges)  //просто пример вывода для теста доступа ко всем ребрам
 {
     Console.WriteLine(Edge.v0 + " " + Edge.v1);
  }
0
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
03.05.2019, 21:10
Цитата Сообщение от ВящЕ Посмотреть сообщение
компилятор пишет что еще должен быть определен set
C# старой версии? В свойствах проекта выберите последнюю версию фреймворка.
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
04.05.2019, 00:03  [ТС]
У меня VS 2012 В СВОЙСТВАХ ПРОЕКТА: Требуемая версия .NET Famevork 4.6.2 и более новую выбрать нельзя.
0
Модератор
Эксперт функциональных языков программирования
3132 / 2279 / 469
Регистрация: 26.03.2015
Сообщений: 8,870
04.05.2019, 15:46
Цитата Сообщение от ВящЕ Посмотреть сообщение
У меня VS 2012
Возможно из-за этого.
Можете сделать по-старинке. Приватное поле класса и к нему паблик свойство с гет.
0
0 / 0 / 0
Регистрация: 19.06.2015
Сообщений: 49
09.05.2019, 16:46  [ТС]
Граф задан списком ребер:
1-4
1-5
4-6
4-7
5-7
6-7
2-5
2-3
2-6
Как я понимаю поиск в глубину будет проходить по графу следующим образом(если не учитывать возвраты в уже посещенные вершины):
1-4
4-6
4-7
6-2
7-5
2-3
5-1 - конец

В моем задании сказано реализовать алгоритм (рекурсивный DFS/BFS) проверки на наличие циклов в графе.
Может ли поиск в глубину придти в уже посещенную вершину по ребрам не составляющим цикл, ведь у меня граф задан ребрами:
1-4
1-5
...


код приложения целиком прелагаю, мне кажется что всё норм.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplicationAandCD2
{
    class Graf //класс не может быть производным от Array?
    {
        //-----------------------------------------------------------------------------------------------------------------------------
        public Graf(int[,] MatricaSmegnosti)                    //конструктор класса Graf
        {
            int kolichectvo_reber = ribs(MatricaSmegnosti, 0); //вычисление количества ребер в формате СПИСОК РЕБЕР //я не разобрался до конца
            int a = kolichectvo_reber, n = (MatricaSmegnosti.GetLength(0)); //b - количество столбцов в матрице СПИСКА РЕБЕР
                                                                                //n - количество строк в матрице смежности(нужно для парсера)
            //блок первода графа из формата МС в СР
            for (int i = 0; i < n; i++)
            {                                       //этот способ парсинга при каждом
                for (int j = i; j < n; j++)         //проходе цикла исключатет пройденую
                {                                   //строку и соответственно пройденый столбец
                    if (MatricaSmegnosti[i, j] == 1)//исключая таким образом уже пройденые варианты
                    {
                        edges.Add(new Edge((i + 1), (j + 1)));  //т.к. элементы в масиве нумеруется начиная с 0 а не с 1 добавляю 1
                    }
                }
            }
            //блок первода графа из формата МС в СР.
 
            Console.WriteLine("edges.Count = " + edges.Count);
            Console.WriteLine("Граф (список ребер):");
            Console.WriteLine();
        }
 
        public class Edge
        {
            //номера вершин
            public int v0;
            public int v1;
 
 
            public Edge(int v0, int v1)
            {
                this.v0 = v0;
                this.v1 = v1;
            }
        }
 
        public List<Edge> edges = new List<Edge>();
        //-----------------------------------------------------------------------------------------------------------------------------
 
        //вычисление количества ребер(по размерности МС) для будущево графа в формате СР
        static int ribs(int[,] m, int a)
        {
            a = 0;
            for (var j = 0; j < m.GetLength(0); j++)
            {
                for (var i = 0; i <= j; i++)
                {
                    if (m[i, j] == 1) a++;
                }
            }
            return a;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            string buf;
            char TaskNumber;
            const int m = 7, n = 7;
            int[,] MatricaSmegnosti = new int[m, n];
            int[] Colors;
            Graf Alpha;
 
            Console.WriteLine("1 - Задание графа с помощю МС \n2 - Ввод графа через консоль \n");
            Console.WriteLine("Введите номер задачи:");
            buf = Console.ReadLine();
            TaskNumber = Char.Parse(buf);
            Console.WriteLine("Выбрана задача: " + TaskNumber);
 
            switch (TaskNumber)
            {
            case '1':
            {
            MatricaSmegnosti = new int[m, n] { //матрица смежности для передачи в качестве входного параметра
            { 0, 0, 0, 1, 1, 0, 0 }, 
            { 0, 0, 1, 0, 1, 1, 0 },
            { 0, 1, 0, 0, 0, 0, 0 },
            { 1, 0, 0, 0, 0, 1, 1 },
            { 1, 1, 0, 0, 0, 0, 1 },
            { 0, 1, 0, 1, 0, 0, 1 },
            { 0, 0, 0, 1, 1, 1, 0 }
            };
            Console.WriteLine("Матрица смежности:");
            Console.WriteLine("Размерность матрицы смежности = " + MatricaSmegnosti.GetLength(0));
 
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    Console.Write(" " + MatricaSmegnosti[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
 
            Alpha = new Graf(MatricaSmegnosti);//создание обекта класса Graf (тупо перевод в СР)
            foreach (Graf.Edge Edge in Alpha.edges)
            {
                Console.WriteLine(Edge.v0 + " " + Edge.v1);
            }
 
            int AmountVertexes = m;             //получение кол-ва вершин в СР обекта Graf
            Console.WriteLine(" AmountVertexes= " + AmountVertexes);
            Colors = new int[AmountVertexes + 1];
            for (int i = 0; i <= AmountVertexes; i++)   //присваеваем единичку каждому элементу массива с 1 до 7 чтоб не путатся со списком(т.к. он тоже от 1 до 7)
            {
                Colors[i] = 1;
            }
            
            Queue<int> vertexes = new Queue<int>();
            Queue<int> Queue = new Queue<int>();
            DFS2(Alpha, Colors, 1, vertexes);
            }break;
 
            case '2':
            {
                        string[] MASstr1;
                        Console.WriteLine("Введите размерность матрицы:");
                        int mn = Convert.ToInt32(Console.ReadLine());
                        int[,] MatrSmeg = new int[mn, mn];
 
                        Console.WriteLine("Введите матрицу смежности разделяя элеметы пробелами\nстроки начиная с новой строки:");
 
                        for (int i = 0; i < mn; i++)
                        {
                            string str = Console.ReadLine();
                            MASstr1 = str.Split(' ');
 
                            for (int j = 0; j < mn; j++)
                            {
                                MatrSmeg[i, j] = Convert.ToInt32(MASstr1[j]);
                            }
                        }
                        
                        Alpha = new Graf(MatrSmeg);//создание обекта класса Graf (тупо перевод в СР)
                        foreach (Graf.Edge Edge in Alpha.edges)
                        {
                            Console.WriteLine(Edge.v0 + " " + Edge.v1);
                        }
 
                        Colors = new int[mn + 1];
                        for (int i = 0; i <= mn; i++)   //присваеваем единичку каждому элементу массива с 1 до 7 чтоб не путатся со списком(т.к. он тоже от 1 до 7)
                        {
                            Colors[i] = 1;
                        }
                        Queue<int> vertexes = new Queue<int>();
                        Queue<int> Queue = new Queue<int>();
                        DFS2(Alpha, Colors, 1, vertexes);
            }break;
            }
        }
 
        static void DFS2(Graf Graf, int[] Colors, int BeginVertex, Queue<int> vertexes, int predok = -1)
        {
            Console.WriteLine("Вход в DFS2");
            Colors[BeginVertex] = 2;    //BeginVertex - 1 ?
            for (int i = 0; i < Graf.edges.Count; i++)
            {                                                                                       
                if (Graf.edges[i].v0 == BeginVertex && Colors[Graf.edges[i].v1] == 1 && Graf.edges[i].v1 != predok)
                {
                    bool NOdeadlock = false;
                    for (int j = 0; j < Graf.edges.Count; j++)
                    {
                        if ((Graf.edges[i].v1 == Graf.edges[j].v0 && Colors[Graf.edges[j].v1] == 1) || (Graf.edges[i].v1 == Graf.edges[j].v1 && Colors[Graf.edges[j].v0] == 1))
                            NOdeadlock = true;
                    }
                    if (NOdeadlock)
                    {
                        vertexes.Enqueue(Graf.edges[i].v0);
                        vertexes.Enqueue(Graf.edges[i].v1);
                    }
 
                    DFS2(Graf, Colors, Graf.edges[i].v1, vertexes, BeginVertex);
                }
                else if (Graf.edges[i].v1 == BeginVertex && Colors[Graf.edges[i].v0] == 1 && Graf.edges[i].v0 != predok)
                {
                    bool NOdeadlock = false;
                    for (int j = 0; j < Graf.edges.Count; j++)
                    {
                        if ((Graf.edges[i].v1 == Graf.edges[j].v0 && Colors[Graf.edges[j].v1] == 1) || (Graf.edges[i].v1 == Graf.edges[j].v1 && Colors[Graf.edges[j].v0] == 1))
                            NOdeadlock = true;
                    }
                    if (NOdeadlock)
                    {
                        vertexes.Enqueue(Graf.edges[i].v0);
                        vertexes.Enqueue(Graf.edges[i].v1);
                    }
                    DFS2(Graf, Colors, Graf.edges[i].v0, vertexes, BeginVertex);
                }
 
                else if ((Graf.edges[i].v0 == BeginVertex && Colors[Graf.edges[i].v1] == 2 && vertexes.Contains(Graf.edges[i].v1) && Graf.edges[i].v1 != predok) || (Graf.edges[i].v1 == BeginVertex && Colors[Graf.edges[i].v0] == 2 && vertexes.Contains(Graf.edges[i].v0) && Graf.edges[i].v0 != predok))
                {
                    if (Colors[Graf.edges[i].v1] == 2)
                    {
                        vertexes.Enqueue(Graf.edges[i].v1);
                        //Colors[Graf.edges[i].v1] = 3;
                    }
 
                    if (Colors[Graf.edges[i].v0] == 2)
                    {
                        vertexes.Enqueue(Graf.edges[i].v0);
                        //Colors[Graf.edges[i].v0] = 3;
                    }
 
                    Console.WriteLine(" ");
                    Console.WriteLine("Граф имеет цикл");
                    foreach (int vertex in vertexes)
                    {
                        Console.Write(vertex + "-");
                    }
                    Console.WriteLine("\n");
                    //vertexes.Clear();
                }
            }
        }
    }
}
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
09.05.2019, 19:42
ВящЕ,
1-4
4-6
6-7
5-7
2-5
2-3
2-6
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.05.2019, 19:42
Помогаю со студенческими работами здесь

Рисование в Windows Forms своим классом
Итак первичная цель: Создать свой класс, в дальнейшем библиотеку, который будет хранить координаты, цвет и форму фигуры для дальнейшей...

Научить cout и printf работать со своим классом
Решил я написать для некоторых своих задач реализацию под C++ тернарной логики. Написал класс tern со всеми необходимыми функциями, и...

Реализация обхода графа в глубину (DFS)
Всем здравствуйте! Задача такова реализация обхода не взвешенного дерева, который задан матрицей смежности и поиск высоты дерева. ...

Шаблон System.Collections.Generic.List со своим классом в качестве параметра
При добавлении методом .Add контейнера List, если в качестве класса у шаблона использовать стандартный класс string - добавляется строка с...

Реализация графов
Помогите пожалуйста!!!!! как написать программу на Си ++ на эту тему :реализация различных типов графов и операций над ними. спасибо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru