-
Notifications
You must be signed in to change notification settings - Fork 2
/
PrimAlgorithm.cs
87 lines (73 loc) · 2.26 KB
/
PrimAlgorithm.cs
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
using System.Collections.Generic;
using System.Linq;
namespace Protsyk.Collections
{
public class PrimAlgorithm
{
public static List<Edge> MinimumSpanningTree(IGraph g)
{
var seen = new HashSet<int>();
var notSeen = new HashSet<int>(g.Vertexes());
var result = new List<Edge>();
var first = notSeen.First();
notSeen.Remove(first);
seen.Add(first);
while (notSeen.Count > 0)
{
var minE = new Edge(0,0,int.MaxValue);
var found = false;
foreach (var s in seen)
{
foreach (var e in g.EdgesFrom(s))
{
if (seen.Contains(e.from)
&& !seen.Contains(e.to)
&& minE.weight > e.weight)
{
minE = e;
found = true;
}
}
}
if (!found)
{
// Graph is not connected
return null;
}
seen.Add(minE.to);
notSeen.Remove(minE.to);
result.Add(minE);
}
return result;
}
public static List<Edge> MinimumSpanningTreeWithHeap(IGraph g)
{
var seen = new HashSet<int>();
var notSeen = new HashSet<int>(g.Vertexes());
var result = new List<Edge>();
var prio = new Heap<Edge>(Comparer<Edge>.Create((x, y) => x.weight - y.weight));
var first = notSeen.First();
notSeen.Remove(first);
seen.Add(first);
foreach (var e in g.EdgesFrom(first))
{
prio.Add(e);
}
while (notSeen.Count > 0)
{
var minE = prio.RemoveTop();
if (seen.Add(minE.to))
{
notSeen.Remove(minE.to);
// Decrease key
foreach (var e in g.EdgesFrom(minE.to))
{
prio.Add(e);
}
result.Add(minE);
}
}
return result;
}
}
}