public void IsDominateZeroLengthTest() { int[] seq1 = new int[0]; int[] seq2 = new int[0]; Assert.False(Stools.IsDominate(seq1, seq2, Cmp.CmpByIComparable)); }
public void IsDominateNullPass2Test() { int[] seq = new int[2] { 1, 2 }; Assert.Throws <ArgumentNullException>(() => Stools.IsDominate(seq, null, Cmp.CmpByIComparable)); }
public void IsDominateDiffLengthsTest() { int[] seq1 = new int[2] { 3, 4 }; int[] seq2 = new int[3] { 1, 2, 3 }; Assert.Throws <ArgumentException>(() => Stools.IsDominate(seq1, seq2, Cmp.CmpByIComparable)); }
public void IsDominateTest() { List <int[]> pairs = new List <int[]> { new int[2] { 0, 0 }, new int[2] { 1, 1 }, new int[2] { 1, 0 }, new int[2] { 1, 1 }, new int[2] { 1, 1 }, new int[2] { 1, 1 }, new int[2] { 2, 1 }, new int[2] { 1, 1 }, new int[2] { 2, 2 }, new int[2] { 1, 1 }, new int[3] { 0, 1, 0 }, new int[3] { 1, 0, 0 } }; bool[] answers = { true, true, false, false, false, false }; int j = 0; for (int i = 0; i < pairs.Count - 1; i += 2) { Assert.True(Stools.IsDominate(pairs[i], pairs[i + 1], Cmp.CmpByIComparable) == answers[j]); j++; } }
/// <summary> /// Recursive procedure. It attributes front's indices to all elements in the /// <paramref name="SeqUniqObjs"/>, with the indices in the <paramref name="Indices"/>, for /// the first <paramref name="CountOfObjs"/> values of the objectives. /// </summary> /// to all elements in the /// <paramref name="SeqUniqObjs"/> /// <param name="SeqUniqObjs"> The sequence of the unique objectives. </param> /// <param name="Fronts"> The values of the fronts. </param> /// <param name="Indices"> The indices of the <paramref name="SeqUniqObjs"/>. </param> /// <param name="CountOfObjs"> /// The number of the values from the objectives, for the sorting. /// </param> private void NdHelperA(IReadOnlyList <TObj>[] SeqUniqObjs, int[] Fronts, LinkedList <int> Indices, int CountOfObjs) { if (Indices.Count < 2) { return; } else if (Indices.Count == 2) { int indexL = Indices.First.Value, indexR = Indices.Last.Value; IEnumerable <TObj> seqObjs1 = SeqUniqObjs[indexL].Take(CountOfObjs); IEnumerable <TObj> seqObjs2 = SeqUniqObjs[indexR].Take(CountOfObjs); if (Stools.IsDominate(seqObjs1, seqObjs2, _objCmp)) { Fronts[indexR] = Math.Max(Fronts[indexR], Fronts[indexL] + 1); } } else if (CountOfObjs == 2) { SweepA(SeqUniqObjs, Fronts, Indices); } else { var distinctObjs = (from index in Indices select SeqUniqObjs[index][CountOfObjs - 1]).Distinct().ToArray(); if (distinctObjs.Length == 1) { NdHelperA(SeqUniqObjs, Fronts, Indices, CountOfObjs - 1); } else { TObj median = Stools.FindLowMedian(distinctObjs, _objCmp); LinkedList <int> lessMedian, equalMedian, greaterMedian, lessAndEqual; SplitBy(SeqUniqObjs, Indices, median, CountOfObjs - 1, out lessMedian, out equalMedian, out greaterMedian); lessAndEqual = MergeLists(lessMedian, equalMedian); NdHelperA(SeqUniqObjs, Fronts, lessMedian, CountOfObjs); NdHelperB(SeqUniqObjs, Fronts, lessMedian, equalMedian, CountOfObjs - 1); NdHelperA(SeqUniqObjs, Fronts, equalMedian, CountOfObjs - 1); NdHelperB(SeqUniqObjs, Fronts, lessAndEqual, greaterMedian, CountOfObjs - 1); NdHelperA(SeqUniqObjs, Fronts, greaterMedian, CountOfObjs); } } }
private void CheckFronts <T>(T[][] Seq, int[] Fronts) where T : IComparable <T> { int totalFronts = Fronts.Max() + 1; var intersection = Fronts.Intersect(Enumerable.Range(0, totalFronts)); Assert.True(intersection.Count() == totalFronts); // Transform to the dictionary. var keyValues = from item in Fronts.Zip(Seq, (front, oneSeq) => new KeyValuePair <int, T[]>(front, oneSeq)) select item; Dictionary <int, LinkedList <T[]> > dict = new Dictionary <int, LinkedList <T[]> >(Fronts.Max() + 1); // Create dictionary. Keys are indices of the fronts. Values are the sequences correspond // to the index of the front. foreach (var keyValue in keyValues) { if (dict.ContainsKey(keyValue.Key)) { dict[keyValue.Key].AddLast(keyValue.Value); } else { var value = new LinkedList <T[]>(); value.AddLast(keyValue.Value); dict.Add(keyValue.Key, value); } } foreach (int frontIndex in Enumerable.Range(0, dict.Keys.Count - 1)) { foreach (T[] seqCurrFront in dict[frontIndex]) { foreach (T[] seqCurrFront2 in dict[frontIndex]) { Assert.False(Stools.IsDominate(seqCurrFront, seqCurrFront2, Cmp.CmpByIComparable)); Assert.False(Stools.IsDominate(seqCurrFront2, seqCurrFront, Cmp.CmpByIComparable)); } foreach (T[] seqNextFront in dict[frontIndex + 1]) { Assert.False(Stools.IsDominate(seqNextFront, seqCurrFront, Cmp.CmpByIComparable)); } } } }
/// <summary> /// Recursive procedure. It attributes a front's index to all elements in the /// <paramref name="SeqUniqObjs"/>, with the indices in the <paramref name="AssignIndices"/>, /// for the first for the first <paramref name="CountOfObjs"/> values of the objectives, by /// comparing them to elements in the <paramref name="SeqUniqObjs"/>, with the indices in the <paramref name="CompIndices"/>. /// </summary> /// <param name="SeqUniqObjs"> The sequence of the unique objectives. </param> /// <param name="Fronts"> The values of the fronts. </param> /// <param name="CompIndices"> The indices for comparing. </param> /// <param name="AssignIndices"> The indices for assign front. </param> /// <param name="CountOfObjs"> /// The number of the values from the objectives, for the sorting. /// </param> private void NdHelperB(IReadOnlyList <TObj>[] SeqUniqObjs, int[] Fronts, LinkedList <int> CompIndices, LinkedList <int> AssignIndices, int CountOfObjs) { if (CompIndices.Count == 0 || AssignIndices.Count == 0) { return; } else if (CompIndices.Count == 1 || AssignIndices.Count == 1) { foreach (int assignIndex in AssignIndices) { var hv = SeqUniqObjs[assignIndex].Take(CountOfObjs); foreach (int compIndex in CompIndices) { var lv = SeqUniqObjs[compIndex].Take(CountOfObjs); if (Stools.IsDominate(lv, hv, _objCmp) || lv.CmpSeqEqual(hv, _objCmp)) { Fronts[assignIndex] = Math.Max(Fronts[assignIndex], Fronts[compIndex] + 1); } } } } else if (CountOfObjs == 2) { SweepB(SeqUniqObjs, Fronts, CompIndices, AssignIndices); } else { var uniqValuesObjFromCompIndices = (from index in CompIndices select SeqUniqObjs[index][CountOfObjs - 1]).Distinct(); var uniqValuesObjFromAssignIndices = (from index in AssignIndices select SeqUniqObjs[index][CountOfObjs - 1]).Distinct(); TObj minUniqValueObjFromCompIndices, maxUniqValueObjFromCompIndices; TObj minUniqValueObjFromAssignIndices, maxUniqValueObjFromAssignIndices; uniqValuesObjFromAssignIndices.MinMax(out minUniqValueObjFromAssignIndices, out maxUniqValueObjFromAssignIndices, _objCmp); uniqValuesObjFromCompIndices.MinMax(out minUniqValueObjFromCompIndices, out maxUniqValueObjFromCompIndices, _objCmp); ResComp resComp; resComp = ConverterResCmp.ConvertToResCmp(_objCmp(maxUniqValueObjFromCompIndices, minUniqValueObjFromAssignIndices)); if (resComp == ResComp.LE || resComp == ResComp.EQ) { NdHelperB(SeqUniqObjs, Fronts, CompIndices, AssignIndices, CountOfObjs - 1); } else { resComp = ConverterResCmp.ConvertToResCmp(_objCmp(minUniqValueObjFromCompIndices, maxUniqValueObjFromAssignIndices)); if (resComp == ResComp.LE || resComp == ResComp.EQ) { TObj median = Stools.FindLowMedian(uniqValuesObjFromAssignIndices.Union(uniqValuesObjFromCompIndices).ToArray(), _objCmp); LinkedList <int> lessMedian1, equalMedian1, greaterMedian1, lessMedian2, equalMedian2, greaterMedian2; SplitBy(SeqUniqObjs, CompIndices, median, CountOfObjs - 1, out lessMedian1, out equalMedian1, out greaterMedian1); SplitBy(SeqUniqObjs, AssignIndices, median, CountOfObjs - 1, out lessMedian2, out equalMedian2, out greaterMedian2); LinkedList <int> lessAndEqualMedian1 = MergeLists(lessMedian1, equalMedian1); NdHelperB(SeqUniqObjs, Fronts, lessMedian1, lessMedian2, CountOfObjs); NdHelperB(SeqUniqObjs, Fronts, lessMedian1, equalMedian2, CountOfObjs - 1); NdHelperB(SeqUniqObjs, Fronts, equalMedian1, equalMedian2, CountOfObjs - 1); NdHelperB(SeqUniqObjs, Fronts, lessAndEqualMedian1, greaterMedian2, CountOfObjs - 1); NdHelperB(SeqUniqObjs, Fronts, greaterMedian1, greaterMedian2, CountOfObjs); } } } }