Exemplo n.º 1
0
            /// <summary>Creates an instance and performs partition</summary>
            /// <param name="nmbs">identified values to be distributed</param>
            /// <param name="result">final result</param>
            /// <param name="avr">average value sum</param>
            /// <param name="limMult">
            ///     DSTree method call's limit multiplier;
            ///     if 0 then omit DSTree method invoking
            /// </param>
            public Partition(IdNumbers nmbs, Result result, float avr, byte limMult)
            {
                numbs       = nmbs;
                finalResult = result;
                avrSum      = avr;
                isAvrFract  = (int)avrSum != avrSum;
                callLimit   = minCallLimit * limMult;
                sumDiff     = largestSum;
                ushort ssCnt = finalResult.SubsetCount;
                int    i     = 0;

                methods[i++] = UGreedy;
                methods[i++] = WrapGreedy;
                methods[i++] = SGreedy;
                methods[i++] = ISTree;
                numbs.SortByDescent();
                int cnt = limMult > 0 ? 4 : 3;

                // for the degenerate case numbs.Count<=ssCnt method UGreedy() is comepletely enough
                if (numbs.Count <= ssCnt)
                {
                    cnt = 1;
                }
                for (i = 0; i < cnt; i++)
                {
                    if (DoPartition(i, ssCnt))
                    {
                        return;
                    }
                }
            }
Exemplo n.º 2
0
 /// <summary>Copies bin's indexes</summary>
 internal void CopyIndexes(IdNumbers numbers)
 {
     for (int i = 0; i < Count; i++)
     {
         this[i].BinIInd = numbers[i].BinIInd;
     }
 }
Exemplo n.º 3
0
 internal IdNumbers(IdNumbers numbers)
 {
     Capacity = numbers.Capacity;
     foreach (IdNumber n in numbers)
     {
         Add(new IdNumber(n));
     }
 }
Exemplo n.º 4
0
 /// <summary>Initializes partition by identified numbers.</summary>
 /// <param name="numbs">identified numbers to be distributed</param>
 /// <param name="ssCnt">count of subsets</param>
 /// <param name="limMult">
 ///     DSTree method call's limit multiplier;
 ///     if 0 then omit DSTree method invoking (fast, but not 'perfect)
 /// </param>
 private void Init(IdNumbers numbs, ushort ssCnt, byte limMult)
 {
     result = new Result(numbs.Count, ssCnt);
     if (ssCnt == 0)
     {
         return;
     }
     Partition Partition = new(numbs, result, avr = numbs.AvrSum(ssCnt), limMult);
 }
Exemplo n.º 5
0
            /// <summary>Outfits this result</summary>
            /// <param name="numbs">numbers to be distributed</param>
            /// <param name="ind">index of the first subset: 1 for SGreedy() or 0 for DSTree()</param>
            /// <param name="diff">difference between the subset sums</param>
            internal void Fill(IdNumbers numbs, byte ind, ulong diff)
            {
                ushort ssCnt = (ushort)(SubsetCount - ind);  // count of subsets minus first index

                Clear();
                foreach (IdNumber n in numbs)
                {
                    Bins[ssCnt - n.BinIInd].AddNumb(n);
                }
                SumDiff = diff;
            }
Exemplo n.º 6
0
            /// <summary>Performs iterative 'Dynamic Search Tree' partition.</summary>
            /// <param name="ssCnt">count of subsets</param>
            private void ISTree(ushort ssCnt)
            {
                // initial range expansion around average
                uint up = avrSum < numbs[0].Val ? numbs[0].Val - Convert.ToUInt32(avrSum) + 2 : 1;

                if (up > avrSum)
                {
                    up = Convert.ToUInt32(avrSum) - 1;
                }
                standbySumDiff = largestSum; // undefined standby inaccuracy
                lastSumDiff    = finalResult.SumDiff;
                standbyNumbs   = new IdNumbers(numbs);
                do
                {
                    minSum  = (ulong)(avrSum - up);
                    maxSum  = (ulong)(avrSum + up);
                    sumDiff = maxSum - minSum;
                    callCnt = complete = 0;
                    numbs.Reset();
                    currResult.Clear();
                    DSTree(0, (ushort)(ssCnt - 1));

                    if (IsCompleteByPerfect || (up *= 2) >= minSum) // increase and checkup range expansion
                    {
                        break;
                    }
                    if (currResult.SumDiff > standbySumDiff) // is current result worse than standby one?
                    {
                        break;
                    }
                } while (lastSumDiff != currResult.SumDiff); // until previous and current inaccuracy are different

                // use last fitted result
                {
                    SetRange(finalResult);
                    finalResult.Fill(standbyNumbs, 1, standbySumDiff);
                }
            }
Exemplo n.º 7
0
 /// <summary>
 ///     Constructs numbers partition by identified numbers,
 ///     with sums sorted in descending order.
 /// </summary>
 /// <param name="numbs">identified numbers to be distributed</param>
 /// <param name="ssCnt">
 ///     count of subsets;
 ///     if 0 then creates an empty partition with undefined (maximum type's value) inaccuracy
 /// </param>
 /// <param name="limMult">
 ///     DSTree method call's limit multiplier -
 ///     it increases the limit of 1 million recursive invokes by limMult times;
 ///     if 0 then omit DSTree method invoking (fast, but not 'perfect')
 /// </param>
 public effPartition(IdNumbers numbs, ushort ssCnt, byte limMult = 1)
 {
     Init(numbs, ssCnt, limMult);
 }