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, 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 LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2) { var length = p1.Length; var child = new LinearLinkage(length); var endNodes = new HashSet<int>(); for (var i = 0; i < length; i++) { if ((p1[i] == i && p2[i] == i) || ((p1[i] == i || p2[i] == i) && random.NextDouble() < 0.5)) { child[i] = i; endNodes.Add(i); } } for (var i = 0; i < length; i++) { if (endNodes.Contains(i)) continue; var p1End = endNodes.Contains(p1[i]); var p2End = endNodes.Contains(p2[i]); if ((p1End && p2End) || (!p1End && !p2End)) { child[i] = random.NextDouble() < 0.5 ? p1[i] : p2[i]; } else if (p1End) { child[i] = p1[i]; } else { child[i] = p2[i]; } } child.LinearizeTreeStructures(); return child; }
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 Swap2Move[] Apply(LinearLinkage lle, IRandom random, int sampleSize) { int length = lle.Length; Swap2Move[] moves = new Swap2Move[sampleSize]; for (int i = 0; i < sampleSize; i++) { moves[i] = StochasticSwap2SingleMoveGenerator.Apply(lle, random); } return moves; }
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 tries = lle.Length; var index = random.Next(lle.Length); while (tries > 0 && lle[index] == index) { index = random.Next(lle.Length); tries--; } if (lle[index] != index) Apply(random, lle, index); }
public static LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2) { var length = p1.Length; var child = new LinearLinkage(length); var bp = random.Next(length - 1); for (var i = 0; i <= bp; i++) child[i] = p1[i]; for (var i = bp + 1; i < length; i++) child[i] = p2[i]; child.LinearizeTreeStructures(); return child; }
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 IEnumerable<Swap2Move> Generate(LinearLinkage lle) { int length = lle.Length; if (length == 1) throw new ArgumentException("ExhaustiveSwap2MoveGenerator: There cannot be an Swap move given only one item.", "lle"); var groups = lle.GetGroups().ToList(); if (groups.Count == 1) throw new InvalidOperationException("ExhaustiveSwap2MoveGenerator: Swap moves cannot be applied when there is only one group."); for (int i = 0; i < groups.Count; i++) for (int j = i + 1; j < groups.Count; j++) for (var k = 0; k < groups[i].Count; k++) for (var m = 0; m < groups[j].Count; m++) { yield return new Swap2Move(groups[i][k], groups[j][m]); } }
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 Swap2Move Apply(LinearLinkage lle, IRandom random) { int length = lle.Length; if (length < 2) throw new ArgumentException("StochasticSwap2SingleMoveGenerator: There cannot be a swap-2 move given only one item.", "lle"); var groups = lle.GetGroups().ToList(); if (groups.Count == 1) throw new InvalidOperationException("StochasticSwap2SingleMoveGenerator: Swap moves cannot be applied when there is only one group."); int index1 = random.Next(groups.Count), index2 = 0; do { index2 = random.Next(length); } while (index1 == index2); var item1 = random.Next(groups[index1].Count); var item2 = random.Next(groups[index2].Count); return new Swap2Move(groups[index1][item1], groups[index2][item2]); }
public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) { var len = parents[0].Length; var child = new LinearLinkage(len); var remaining = new SortedSet<int>(Enumerable.Range(0, len)); do { var groups = parents.Select(x => x.GetGroupForward(remaining.Min).Where(y => remaining.Contains(y)).ToList()).ToList(); var max = groups.Select((v, idx) => Tuple.Create(idx, v.Count)).MaxItems(x => x.Item2).SampleRandom(random).Item1; var i = groups[max][0]; for (var k = 1; k < groups[max].Count; k++) { child[i] = groups[max][k]; remaining.Remove(i); i = child[i]; } child[i] = i; remaining.Remove(i); } while (remaining.Count > 0); return child; }
public static void Apply(IRandom random, LinearLinkage lle, int index) { var groups = lle.Select((val, idx) => Tuple.Create(idx, val)) .Where(x => x.Item1 == x.Item2) .Select(x => x.Item2).ToList(); var z = groups.Count; if (random.NextDouble() < 0.5) lle[index] = index; // divide the cluster into two else { var c = random.Next(z); if (groups[c] > index) lle[index] = groups[c]; // combine the portion with another class else { // combine the other class here lle[groups[c]] = lle[index]; lle[index] = index; } lle.LinearizeTreeStructures(); } }
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 p = random.Next(parents.Length); var child = new LinearLinkage(len); var remaining = new SortedSet<int>(Enumerable.Range(0, len)); do { var i = remaining.Min; foreach (var g in parents[p].GetGroupForward(i)) { if (!remaining.Contains(g)) continue; child[i] = g; i = g; remaining.Remove(g); } child[i] = i; remaining.Remove(i); p = (p + 1) % parents.Length; } while (remaining.Count > 0); return child; }
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)); }
protected override Swap2Move[] GenerateMoves(LinearLinkage lle) { IRandom random = RandomParameter.ActualValue; return new[] { Apply(lle, random) }; }
protected override void Manipulate(IRandom random, LinearLinkage lle) { Apply(random, lle); }
protected abstract void Manipulate(IRandom random, LinearLinkage lle);
protected override void Manipulate(IRandom random, LinearLinkage lle) { var N = NParameter.ActualValue.Value; Apply(random, lle, N); }
protected abstract Swap2Move[] GenerateMoves(LinearLinkage lle);
protected override Swap2Move[] GenerateMoves(LinearLinkage lle) { IRandom random = RandomParameter.ActualValue; return(Apply(lle, random, SampleSizeParameter.ActualValue.Value)); }
protected abstract EMSSMove[] GenerateMoves(LinearLinkage lle);
protected override Swap2Move[] GenerateMoves(LinearLinkage lle) { IRandom random = RandomParameter.ActualValue; return Apply(lle, random, SampleSizeParameter.ActualValue.Value); }
public Swap2Move(int item1, int item2, LinearLinkage lle) : base() { Item1 = item1; Item2 = item2; LLE = lle; }
private LinearLinkage(LinearLinkage original, Cloner cloner) : base(original, cloner) { }
protected override Swap2Move[] GenerateMoves(LinearLinkage lle) { return Generate(lle).ToArray(); }