-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSolution.cs
More file actions
229 lines (208 loc) · 6.45 KB
/
Copy pathSolution.cs
File metadata and controls
229 lines (208 loc) · 6.45 KB
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
namespace genetic_algorithm_graph_partitioning;
using System;
/// <summary>
/// Represents a solution for the graph partitioning problem.
/// </summary>
public class Solution
{
/// <summary>
/// Partitioning of the graph.
/// </summary>
private int[]? partitioning;
/// <summary>
/// The number of partitions.
/// </summary>
private int partion_count;
/// <summary>
/// The score of the partitioning.
/// </summary>
private int score;
/// <summary>
/// The number of passes in the Fiduccia-Mattheyses algorithm.
/// </summary>
private int fm_passes;
/// <summary>
/// Random number generator.
/// </summary>
private static Random rnd = new Random();
/// <summary>
/// Initializes a new instance of the <see cref="Solution"/> class with a random partitioning.
/// </summary>
/// <param name="size">The size of the partitioning.</param>
/// <param name="partions">The number of partitions (default is 2).</param>
public Solution(int size, int partions = 2)
{
partion_count = partions;
fm_passes = 0;
partitioning = new int[size];
score = Int32.MaxValue;
int count_ones;
int count_zeros;
do
{
count_ones = 0;
count_zeros = 0;
for (int i = 0; i < partitioning.Count(); i++)
{
partitioning[i] = rnd.Next(partion_count);
if (partitioning[i] == 1)
count_ones++;
else if (partitioning[i] == 0)
count_zeros++;
else
throw new Exception("Invalid Random Outcome");
}
} while (count_ones != partitioning.Count() / 2 || count_zeros != partitioning.Count() / 2);
}
/// <summary>
/// Initializes a new instance of the <see cref="Solution"/> class with a given partitioning.
/// </summary>
/// <param name="partitioning">The initial partitioning.</param>
/// <param name="partions">The number of partitions (default is 2).</param>
public Solution(int[] partitioning, int partions = 2)
{
this.partion_count = partions;
fm_passes = 0;
score = Int32.MaxValue;
this.partitioning = new int[partitioning.Count()];
for (int i = 0; i < partitioning.Count(); i++)
{
this.partitioning[i] = partitioning[i];
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Solution"/> class with a given partitioning and score.
/// </summary>
///
/// <param name="partitioning">The initial partitioning.</param>
/// <param name="partions">The number of partitions (default is 2).</param>
/// <param name="score">The score of the partitioning.</param>
public Solution(int[] partitioning, int partions, int score)
{
this.partion_count = partions;
this.score = score;
fm_passes = 0;
this.partitioning = new int[partitioning.Count()];
for (int i = 0; i < partitioning.Count(); i++)
{
this.partitioning[i] = partitioning[i];
}
}
/// <summary>
/// Gets the current partitioning.
/// </summary>
/// <returns>An array representing the current partitioning.</returns>
public int[] GetPartitioning()
{
if (partitioning == null)
return new int[0];
return partitioning;
}
/// <summary>
/// Sets the partitioning to a new value.
/// </summary>
/// <param name="new_partioning">The new partitioning.</param>
public void SetPartitioning(int[] new_partioning)
{
this.partitioning = new_partioning;
}
/// <summary>
/// Switches the value of a specific index in the partitioning.
/// </summary>
/// <param name="index">The index to switch.</param>
/// <param name="value">The new value.</param>
public void SwitchPartitioning(int index, int value)
{
if (partitioning != null)
this.partitioning[index] = value;
}
/// <summary>
/// Switches the value of a specific index in the partitioning.
/// </summary>
///
/// <param name="index">The index to switch.</param>
public void SwitchPartitioning(int index)
{
if (partitioning != null)
this.partitioning[index] = (this.partitioning[index] + 1) % partion_count;
}
/// <summary>
/// Overrides the ToString method.
/// </summary>
///
/// <returns>A string representation of the partitioning.</returns>
public override string ToString()
{
return string.Join(" ", partitioning ?? new int[0]);
}
/// <summary>
/// Overrides the Clone method.
/// </summary>
///
/// <returns>A clone of a solution object</returns>
public Solution Clone()
{
if (partitioning == null)
return new Solution(0);
return new Solution(partitioning, partion_count, score);
}
/// <summary>
/// Checks the validity of a solution.
/// </summary>
///
/// <param name="groups">The number of groups to check for validity (default is 2).</param>
/// <returns>True if the solution is valid, false otherwise.</returns>
public bool IsValid(int groups = 2)
{
if (partitioning == null)
return false;
int[] vals = new int[groups];
for (int i = 0; i < partitioning.Count(); i++)
{
vals[partitioning[i]]++;
}
int test = vals[0];
for (int i = 0; i < vals.Count(); i++)
{
if (test != vals[i])
return false;
}
return true;
}
/// <summary>
/// Returns the score of the solution.
/// </summary>
///
/// <returns>The score of the solution.</returns>
public int Score()
{
return score;
}
/// <summary>
/// Sets the score of the solution.
/// </summary>
///
/// <param name="score">Score to set.</param>
public void SetScore(int score)
{
this.score = score;
}
/// <summary>
/// Sets the Fiduccia-Mattheyses passes.
/// </summary>
///
/// <param name="passes">The number of passes.</param>
public void SetFMPasses(int passes)
{
this.fm_passes = passes;
}
/// <summary>
/// Gets the Fiduccia-Mattheyses passes.
/// </summary>
///
/// <returns>The number of passes.</returns>
public int GetFMPasses()
{
return fm_passes;
}
}