سؤال

لدينا تكلفة C التي يجب أن تسند إلى إدارات 1..n.آخر حساب تنتج حصة كل إدارة ، وهو رقم من 0 إلى 1, مع أكثر من 5 منازل عشرية.مجموع كل قسم سهم هو بالضبط 1 ، ولكنها ليست بالضرورة متساوية.

والهدف من ذلك هو حساب الدقيق دولار وسنت قانون كل قسم.مجموع الفاتورة يجب أن تتطابق تماما مع تكلفة C, فإنه لا يمكن أن يكون بضعة قروش أو أكثر.وعلاوة على ذلك, كل قسم حصة يجب أن لا تتطلب كسور بنسات.بالإضافة إلى ذلك, على الرغم من أنه ليس من العدل أن مجرد تفريغ ما تبقى إلى آخر قسم ، فإنه ليس من الضروري أن ننظر إلى الوراء إلى الأطر الزمنية السابقة.علما أن مجرد التقريب لكل قسم حصة قرش دائما تقريبا النتائج في أكثر/أقل من بضعة قروش.

صارخ التبسيط سبيل المثال:ج = 33.34 , 4 أقسام كل منها بالضبط 0.2500 حصة.لأن 33.34 * 0.25 = 8.335 لذلك يمكنك أن ترى أن الإدارتين يجب دفع 8.33 واثنين يجب أن تدفع 8.34.واحدة صحيحة المهمة ليكون:d1=8.33, d2=8.34, d3=8.33, d4=8.34.إذا كنت في جولة في كل قسم يدفع 8.34 مما يؤدي الفائض من $0.02.إذا كنت ضرب هذا قبل العديد من الإدارات والعديد من التكاليف ، كنت في نهاية المطاف مع مائة دولار التناقضات.

أريد أن أفعل هذا في 1 تمرير, هذا هو, أنا لا أريد أن حلقة من خلال معرفة أنا قبالة بنسبة 0.02, ثم حلقة أخرى وقرص القيم حتى هو الصحيح.أريد أن أفعل هذا في 1 تمريرة.كما أود أن أعرف إذا كان هذا خوارزمية له اسم.

هل كانت مفيدة؟

المحلول

في بيرل:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

use List::AllUtils qw( sum );

print Dumper allocate(10_000, .23, .37, .4);
print Dumper allocate(33.34, .25, .25, .25, .25);
print Dumper allocate(100, 1/3, 1/3, 1/3);

sub allocate {
    my ($C, @shares) = @_;

    my @alloc;

    while ( my $share = shift @shares ) {
        push @alloc, sprintf '%.2f', $C * $share;
        $C -= $alloc[-1];
        my $denom = sum @shares;
        $_ /= $denom for @shares;
    }

    return \@alloc;
}

وإخراج:

$VAR1 = [
          '2300.00',
          '3700.00',
          '4000.00'
        ];
$VAR1 = [
          '8.34',
          '8.33',
          '8.34',
          '8.33'
        ];
$VAR1 = [
          '33.33',
          '33.34',
          '33.33'
        ];

نصائح أخرى

لا تستخدم عوامات. استخدم أحد الأرقام العشرية نقطة ثابتة، أو [إينتس] استخدام تلك التي يمكنك تقسيم بأي عامل التحجيم الخاص بك هو الحصول على قيمة بالدولار.

وأبدا، أبدا، <م> من أي وقت مضى حساب المال باستخدام عوامات.

أنا أسميه "تشغيل" وتنفيذ ذلك على النحو التالي:

  1. حساب حصة المستحق قسم #1 (قد أخطاء التقريب)
  2. جعل قسم #1 دفع المبلغ المحسوب في الخطوة 1
  3. حساب حصة هذا بالاشتراك المستحق قسم #1 و قسم #2
  4. جعل قسم #1 دفع المبلغ المحسوب في الخطوة 3 ، ناقص المبلغ المدفوع فعلا في الخطوة 2.
  5. الخ.عن المبلغ الذي بالاشتراك المستحقة على الديون #s 1 ، 2 ، 3.

وهذا يضمن أن الخطأ من ذوي الخبرة من أي قسم هو واحد على الأكثر خطأ التقريب (لا مبلغ من عدة أخطاء التقريب) ، المجموع النهائي هو الصحيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top