예제 #1
0
        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]));
                        }
                    }
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
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().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);
        }
예제 #6
0
    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 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]));
        }
예제 #8
0
        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 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]);
            }
    }
예제 #10
0
    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]);
    }
예제 #12
0
    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);
    }
예제 #13
0
    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));
    }
예제 #14
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);
        }