public void FindLowMedianStructTest() { for (int i = 1; i <= MAX_SIZE; i++) { int[] seq = CreateAndInitArrayForTest(i, typeof(int)).Cast <int>().ToArray(); int median = Stools.FindLowMedian(seq, Cmp.CmpByIComparable); Array.Sort(seq); Assert.Equal <int>(median, seq[(seq.Length - 1) / 2]); } }
public void FindLowMedianClassTest() { for (int i = 1; i <= MAX_SIZE; i++) { DoubleClass[] seq = CreateAndInitArrayForTest(i, typeof(DoubleClass)).Cast <DoubleClass>().ToArray(); DoubleClass median = Stools.FindLowMedian(seq, (a, b) => a.CompareTo(b)); Array.Sort(seq); Assert.Equal <DoubleClass>(median, seq[(seq.Length - 1) / 2]); } }
/// <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); } } }
/// <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); } } } }
public void FindLowMedianZeroLengthTest() { Assert.Throws <ArgumentException>(() => Stools.FindLowMedian(new int[0] { }, Cmp.CmpByIComparable)); }
public void FindLowMedianNullPassTest() { int[] seq = null; Assert.Throws <ArgumentNullException>(() => Stools.FindLowMedian(seq, Cmp.CmpByIComparable)); }