public static LinearLinkage Apply(IRandom random, ItemArray <LinearLinkage> parents)
        {
            var len       = parents[0].Length;
            var p         = random.Next(parents.Length);
            var child     = LinearLinkage.SingleElementGroups(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 LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2)
        {
            var length = p1.Length;
            var child  = LinearLinkage.SingleElementGroups(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, ItemArray <LinearLinkage> parents)
        {
            var len       = parents[0].Length;
            var child     = LinearLinkage.SingleElementGroups(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);
        }