graph-builder
/
algorythms.go
157 строк · 4.1 Кб
1package graph
2
3import (
4"sort"
5)
6
7// DFS Поиск в глубину для невзвешенного графа
8func (g *AbstractGraph[T]) DFS(start T, compare func(want T) bool) ([]*Node[T], bool) {
9var searchStack []*Node[T]
10for vert := range g.Graph {
11if vert.Name == start {
12searchStack = append(searchStack, vert)
13break
14}
15}
16for len(searchStack) != 0 {
17var vertex = searchStack[len(searchStack)-1]
18searchStack = searchStack[:len(searchStack)-1]
19if vertex.Mark != 1 {
20if compare(vertex.Name) {
21g.Unmark()
22g.Vertexes = append(g.Vertexes, vertex)
23return g.Vertexes, true
24}
25vertex.Mark = 1
26g.Vertexes = append(g.Vertexes, vertex)
27searchStack = append(searchStack, g.GetAdjacentVertices(vertex)...)
28}
29}
30g.Unmark()
31return nil, false
32}
33
34// BFS Поиск в ширину
35func (g *AbstractGraph[T]) BFS(start T, compare func(want T) bool) ([]*Node[T], bool) {
36var searchQueue []*Node[T]
37for vert := range g.Graph {
38if vert.Name == start {
39searchQueue = append(searchQueue, vert)
40break
41}
42}
43for len(searchQueue) != 0 {
44var vertex = searchQueue[0]
45searchQueue = searchQueue[1:]
46if vertex.Mark != 1 {
47if compare(vertex.Name) {
48g.Unmark()
49g.Vertexes = append(g.Vertexes, vertex)
50return g.Vertexes, true
51}
52vertex.Mark = 1
53g.Vertexes = append(g.Vertexes, vertex)
54searchQueue = append(searchQueue, g.GetAdjacentVertices(vertex)...)
55}
56
57}
58g.Unmark()
59return nil, false
60}
61
62// Painting Раскраска графа
63func (g *AbstractGraph[T]) Painting() map[T][]int {
64colors := randomColorsInRGB(len(g.Graph))
65i := 0
66var vList = make([]*Node[T], len(g.Graph))
67for vert := range g.Graph {
68vList[i] = vert
69i++
70}
71// сортируем список вершин по убыванию степени
72sort.Slice(vList, func(i, j int) bool {
73return vList[i].Power > vList[j].Power
74})
75i = 0
76var output = make(map[T][]int, len(g.Graph))
77// проходим по списку вершин
78for _, vert := range vList {
79if vert.Mark == 1 {
80continue
81}
82output[vert.Name] = colors[i]
83vert.Mark = 1
84subVerts := g.Graph[vert]
85// и еще раз, чтобы покрасить все несмежные
86for _, vertex := range vList {
87if !checkIfIn(subVerts, vertex) && vertex.Mark != 1 {
88output[vertex.Name] = colors[i]
89vertex.Mark = 1
90}
91}
92i++
93}
94g.Unmark()
95return output
96}
97
98// Cycle - поиск цикла в графе на основе поиска в глубину (TODO НЕ ДОДЕЛАНО, нужна помощь)
99func (g *AbstractGraph[T]) Cycle(start T) []*Node[T] {
100var searchStack, output []*Node[T]
101var startNode *Node[T]
102for vert := range g.Graph {
103if vert.Name == start {
104searchStack = append(searchStack, vert)
105startNode = vert
106break
107}
108}
109for len(searchStack) != 0 {
110var vertex = searchStack[len(searchStack)-1]
111searchStack = searchStack[:len(searchStack)-1]
112if vertex.Mark != 1 {
113vertex.Mark = 1
114output = append(output, vertex)
115searchStack = append(searchStack, g.GetAdjacentVertices(vertex)...)
116if checkIfIn(g.Graph[vertex], startNode) && len(output) > 2 {
117output = append(output, startNode)
118return output
119}
120}
121}
122return nil
123}
124
125// Dijkstra Алгоритм Дейкстры поиска кратчайших путей из вершины в графе.
126func (g *AbstractGraph[T]) Dijkstra(start, end T) map[*Node[T]]int {
127var processed []*Node[T]
128var endNode, _temp *Node[T]
129var nodeParents, vertCosts = make(map[*Node[T]]*Node[T], len(g.Graph)), make(map[*Node[T]]int, len(g.Graph))
130for vert := range g.Graph {
131if vert.Name == start {
132for kid := range g.Graph[vert] {
133nodeParents[kid] = vert
134vertCosts[kid] = g.Graph[vert][kid]
135}
136}
137if vert.Name == end {
138endNode = vert
139}
140}
141nodeParents[endNode] = nil
142_temp = findMinimalCostNode(vertCosts, processed)
143for _temp != nil {
144cost := vertCosts[_temp]
145neighbours := g.Graph[_temp]
146for node := range neighbours {
147newCost := cost + neighbours[node]
148if vertCosts[node] > newCost {
149vertCosts[node] = newCost
150nodeParents[node] = node
151}
152}
153processed = append(processed, _temp)
154_temp = findMinimalCostNode(vertCosts, processed)
155}
156return vertCosts
157}
158