public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); grouping.Add(new List <int>()); // add an empty group for (var i = 0; i < n; i++) { var src = random.Next(grouping.Count - 1); // only select from non-empty groups var dest = random.Next(grouping.Count); while (src == dest || grouping[src].Count == 1 && dest == grouping.Count - 1) { src = random.Next(grouping.Count - 1); dest = random.Next(grouping.Count); } if (dest == grouping.Count - 1) { grouping.Add(new List <int>()); } var e = random.Next(grouping[src].Count); grouping[dest].Add(grouping[src][e]); grouping[src].RemoveAt(e); if (grouping[src].Count == 0) { grouping.RemoveAt(src); } } lle.SetGroups(grouping.Where(x => x.Count > 0)); }
/// <summary> /// Create a new LinearLinkage object by translating /// an enumeration of groups into the underlying array representation. /// </summary> /// <remarks> /// Throws an ArgumentException when there is an element assigned to /// multiple groups or elements that are not assigned to any group. /// </remarks> /// <param name="grouping">The grouping of the elements, each element must /// be part of exactly one group.</param> public static LinearLinkage FromGroups(int length, IEnumerable <IEnumerable <int> > grouping) { var result = new LinearLinkage(length); result.SetGroups(grouping); return(result); }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().Select(x => x.ToList()).ToList(); if (grouping.Count == 1) { return; // nothing can be changed } var prevGroup = random.Next(grouping.Count); var prevItem = random.Next(grouping[prevGroup].Count); for (var i = 0; i < n; i++) { int nextGroup, nextItem; do { nextGroup = random.Next(grouping.Count); nextItem = random.Next(grouping[nextGroup].Count); } while (nextGroup == prevGroup); var h = grouping[nextGroup][nextItem]; grouping[nextGroup][nextItem] = grouping[prevGroup][prevItem]; grouping[prevGroup][prevItem] = h; prevGroup = nextGroup; prevItem = nextItem; } lle.SetGroups(grouping); }
public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) { var len = parents[0].Length; var child = new LinearLinkage(len); var childGroup = new List<HashSet<int>>(); var currentParent = random.Next(parents.Length); var groups = parents.Select(x => x.GetGroups().Select(y => new HashSet<int>(y)).ToList()).ToList(); bool remaining; do { var maxGroup = groups[currentParent].Select((v, i) => Tuple.Create(i, v)) .MaxItems(x => x.Item2.Count) .SampleRandom(random).Item1; var group = groups[currentParent][maxGroup]; groups[currentParent].RemoveAt(maxGroup); childGroup.Add(group); remaining = false; for (var p = 0; p < groups.Count; p++) { for (var j = 0; j < groups[p].Count; j++) { foreach (var elem in group) groups[p][j].Remove(elem); if (!remaining && groups[p][j].Count > 0) remaining = true; } } currentParent = (currentParent + 1) % parents.Length; } while (remaining); child.SetGroups(childGroup); return child; }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); if (grouping.Count == 1) { return; // nothing to merge } for (var i = 0; i < n; i++) { var g1 = random.Next(grouping.Count); var g2 = random.Next(grouping.Count); while (g1 == g2) { g2 = random.Next(grouping.Count); } grouping[g1].AddRange(grouping[g2]); grouping.RemoveAt(g2); if (grouping.Count == 1) { break; } } lle.SetGroups(grouping); }
public static LinearLinkage Apply(IRandom random, int length, int maxGroups) { var solution = new LinearLinkage(length); var groups = Enumerable.Range(0, length).Select(x => Tuple.Create(x, random.Next(maxGroups))) .GroupBy(x => x.Item2) .Select(x => x.Select(y => y.Item1).ToList()); solution.SetGroups(groups); return solution; }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); var groupsLargerOne = grouping.Select((v, i) => Tuple.Create(i, v)) .Where(x => x.Item2.Count > 1) .ToDictionary(x => x.Item1, x => x.Item2); if (groupsLargerOne.Count == 0) { return; } var toRemove = new List <int>(); for (var i = 0; i < n; i++) { var g = groupsLargerOne.Keys.SampleRandom(random); var idx = random.Next(1, groupsLargerOne[g].Count); // shuffle here to avoid a potential bias of grouping smaller and larger numbers together var tmp = groupsLargerOne[g].Shuffle(random); var before = new List <int>(); var after = new List <int>(); foreach (var t in tmp) { if (idx > 0) { before.Add(t); } else { after.Add(t); } idx--; } if (before.Count > 1) { groupsLargerOne[grouping.Count] = before; } grouping.Add(before); if (after.Count > 1) { groupsLargerOne[grouping.Count] = after; } grouping.Add(after); toRemove.Add(g); groupsLargerOne.Remove(g); if (groupsLargerOne.Count == 0) { break; } } foreach (var r in toRemove.OrderByDescending(x => x)) { grouping.RemoveAt(r); } lle.SetGroups(grouping); }
public static LinearLinkage Apply(IRandom random, int length) { var solution = new LinearLinkage(length); var groups = Enumerable.Range(0, length).Select(x => Tuple.Create(x, random.Next(length))) .GroupBy(x => x.Item2) .Select(x => x.Select(y => y.Item1).ToList()); solution.SetGroups(groups); return(solution); }
public static LinearLinkage Apply(IRandom random, int length, int groups) { var solution = new LinearLinkage(length); var groupNumbers = Enumerable.Range(0, length).Select(x => x % groups).Shuffle(random); var grouping = Enumerable.Range(0, groups).Select(x => new List<int>()).ToList(); var idx = 0; foreach (var g in groupNumbers) grouping[g].Add(idx++); solution.SetGroups(grouping); return solution; }
public static LinearLinkage Apply(IRandom random, int length, int groups) { var solution = new LinearLinkage(length); var groupNumbers = Enumerable.Range(0, length).Select(x => x % groups).Shuffle(random); var grouping = Enumerable.Range(0, groups).Select(x => new List <int>()).ToList(); var idx = 0; foreach (var g in groupNumbers) { grouping[g].Add(idx++); } solution.SetGroups(grouping); return(solution); }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); if (grouping.Count == 1) return; // nothing to merge for (var i = 0; i < n; i++) { var g1 = random.Next(grouping.Count); var g2 = random.Next(grouping.Count); while (g1 == g2) g2 = random.Next(grouping.Count); grouping[g1].AddRange(grouping[g2]); grouping.RemoveAt(g2); if (grouping.Count == 1) break; } lle.SetGroups(grouping); }
public static LinearLinkage Apply(IRandom random, ItemArray <LinearLinkage> parents) { var len = parents[0].Length; var child = new LinearLinkage(len); var childGroup = new List <HashSet <int> >(); var currentParent = random.Next(parents.Length); var groups = parents.Select(x => x.GetGroups().Select(y => new HashSet <int>(y)).ToList()).ToList(); bool remaining; do { var maxGroup = groups[currentParent].Select((v, i) => Tuple.Create(i, v)) .MaxItems(x => x.Item2.Count) .SampleRandom(random).Item1; var group = groups[currentParent][maxGroup]; groups[currentParent].RemoveAt(maxGroup); childGroup.Add(group); remaining = false; for (var p = 0; p < groups.Count; p++) { for (var j = 0; j < groups[p].Count; j++) { foreach (var elem in group) { groups[p][j].Remove(elem); } if (!remaining && groups[p][j].Count > 0) { remaining = true; } } } currentParent = (currentParent + 1) % parents.Length; } while (remaining); child.SetGroups(childGroup); return(child); }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().Select(x => x.ToList()).ToList(); if (grouping.Count == 1) return; // nothing can be changed var prevGroup = random.Next(grouping.Count); var prevItem = random.Next(grouping[prevGroup].Count); for (var i = 0; i < n; i++) { int nextGroup, nextItem; do { nextGroup = random.Next(grouping.Count); nextItem = random.Next(grouping[nextGroup].Count); } while (nextGroup == prevGroup); var h = grouping[nextGroup][nextItem]; grouping[nextGroup][nextItem] = grouping[prevGroup][prevItem]; grouping[prevGroup][prevItem] = h; prevGroup = nextGroup; prevItem = nextItem; } lle.SetGroups(grouping); }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); grouping.Add(new List<int>()); // add an empty group for (var i = 0; i < n; i++) { var src = random.Next(grouping.Count - 1); // only select from non-empty groups var dest = random.Next(grouping.Count); while (src == dest || grouping[src].Count == 1 && dest == grouping.Count - 1) { src = random.Next(grouping.Count - 1); dest = random.Next(grouping.Count); } if (dest == grouping.Count - 1) grouping.Add(new List<int>()); var e = random.Next(grouping[src].Count); grouping[dest].Add(grouping[src][e]); grouping[src].RemoveAt(e); if (grouping[src].Count == 0) grouping.RemoveAt(src); } lle.SetGroups(grouping.Where(x => x.Count > 0)); }
public static void Apply(LinearLinkage lle, Swap2Move move) { var groups = lle.GetGroups().ToList(); int g1 = -1, g2 = -1, g1Idx = -1, g2Idx = -1; for (var i = 0; i < groups.Count; i++) { if (g1 < 0) { g1Idx = groups[i].IndexOf(move.Item1); if (g1Idx >= 0) { g1 = i; continue; } } if (g2 < 0) { g2Idx = groups[i].IndexOf(move.Item2); if (g2Idx >= 0) { g2 = i; } } } // can happen if (for some reason) the items belong to the same group if (g1 < 0 || g2 < 0) { throw new InvalidOperationException("Swap2MoveMaker: Cannot apply swap move, items are not found in different groups."); } var h = groups[g1][g1Idx]; groups[g1][g1Idx] = groups[g2][g2Idx]; groups[g2][g2Idx] = h; lle.SetGroups(groups); }
public static void Apply(IRandom random, LinearLinkage lle, int n) { var grouping = lle.GetGroups().ToList(); var groupsLargerOne = grouping.Select((v, i) => Tuple.Create(i, v)) .Where(x => x.Item2.Count > 1) .ToDictionary(x => x.Item1, x => x.Item2); if (groupsLargerOne.Count == 0) return; var toRemove = new List<int>(); for (var i = 0; i < n; i++) { var g = groupsLargerOne.Keys.SampleRandom(random); var idx = random.Next(1, groupsLargerOne[g].Count); // shuffle here to avoid a potential bias of grouping smaller and larger numbers together var tmp = groupsLargerOne[g].Shuffle(random); var before = new List<int>(); var after = new List<int>(); foreach (var t in tmp) { if (idx > 0) before.Add(t); else after.Add(t); idx--; } if (before.Count > 1) groupsLargerOne[grouping.Count] = before; grouping.Add(before); if (after.Count > 1) groupsLargerOne[grouping.Count] = after; grouping.Add(after); toRemove.Add(g); groupsLargerOne.Remove(g); if (groupsLargerOne.Count == 0) break; } foreach (var r in toRemove.OrderByDescending(x => x)) grouping.RemoveAt(r); lle.SetGroups(grouping); }
public static void Apply(LinearLinkage lle, Swap2Move move) { var groups = lle.GetGroups().ToList(); int g1 = -1, g2 = -1, g1Idx = -1, g2Idx = -1; for (var i = 0; i < groups.Count; i++) { if (g1 < 0) { g1Idx = groups[i].IndexOf(move.Item1); if (g1Idx >= 0) { g1 = i; continue; } } if (g2 < 0) { g2Idx = groups[i].IndexOf(move.Item2); if (g2Idx >= 0) g2 = i; } } // can happen if (for some reason) the items belong to the same group if (g1 < 0 || g2 < 0) throw new InvalidOperationException("Swap2MoveMaker: Cannot apply swap move, items are not found in different groups."); var h = groups[g1][g1Idx]; groups[g1][g1Idx] = groups[g2][g2Idx]; groups[g2][g2Idx] = h; lle.SetGroups(groups); }