【问题标题】:Calculate percent at runtime在运行时计算百分比
【发布时间】:2010-12-20 20:08:57
【问题描述】:

我有这个问题,我必须“审核”我的交易百分比。

如果百分比是 100,我必须全部审核,如果是 0,我必须全部跳过,如果 50% 我必须检查一半等等。

问题(或机会)是我必须在运行时执行检查。

我尝试的是:

audit = 100/percent 

所以如果百分比是 50

audit = 100 / 50 ( which is 2 ) 

所以我必须审核 1 并跳过 1 审核 1 并跳过 1 ..

如果是 30

审计 = 100 / 30 ( 3.3 )

我审核 2 并跳过第三个。

问题

我遇到了超过 50%(比如 75%)的数字问题,因为它给了我 1.333,...

什么时候才是正确的算法来知道要审计多少?...我也有 0 的问题(由于除以 0 :P),但我已经解决了这个问题,还有 100 等等。

非常感谢任何建议。

【问题讨论】:

  • 首先,在您的“审核 30%”示例中,您最终将审核 33% 您审核的所有交易是否必须均匀分布?还是所有交易都来自列表的头部(例如,如果您必须审核 30%,您可以只审核前 30% 的交易吗?
  • number_of_items = (percent) * (total_number_of_items) 其中百分比为 [0,1](因此,如果您有 [0,100],则除以 100)。
  • 一般审计应该是随机的。您的算法不是随机的,可能很容易被规避。如果您在金融环境中使用它,您应该调整您的算法。

标签: c# java python algorithm language-agnostic


【解决方案1】:

要遵循您自己的算法:只需将 1.333333(或其他商)添加到计数器即可。

有两个计数器:一个整数 1 和一个实数。如果真实计数器的截断部分=整数计数器,则进行审计,否则不进行,像这样:

Integer counter   Real counter

1                 1.333333: audit transaction
2                 2.666666: audit transaction
3                 3.999999: audit transaction
4                 truncated(5.333333) = 5 > 4 => do NOT audit transaction
5                 5.333333: audit transaction

仅当实际计数器的截断版本 = 整数计数器时才增加实际计数器。始终递增整数计数器。

在代码中:

var p, pc: double;
    c: integer;
begin
  p := 100 / Percentage;
  pc := p;
  for c := 1 to NrOfTransactions do begin
    if trunc(pc) = c then begin
      pc := pc + p;
      Do audit on transaction c
    end  
  end;
end;

【讨论】:

    【解决方案2】:
        if percent > random.randint(1,100):
            print("audit")
        else:
            print("skip")
    

    【讨论】:

      【解决方案3】:

      未测试,但在random 模块中有一个函数sample。如果transactions 是一个交易列表,你可以这样做:

      import random
      
      to_be_audited = random.sample(transactions,len(transactions*100/percentage))
      

      这将生成一个列表to_be_audited,这是一个随机的、非重复的交易样本。

      documentation on random

      【讨论】:

        【解决方案4】:

        您可以使用计数器不断“查询”每个审计。例如

        ctr = 0;
        percent = 50
        while(1) {
           ctr += percent;
           if (ctr >= 100) {
              audit;
              ctr = ctr - 100;
           } else
              skip
        }
        

        您可以使用浮点数(但这会带来一些不可预测性)或将 100% 乘以某物以获得更好的分辨率。

        真的没有必要使用随机数生成器。

        【讨论】:

          【解决方案5】:

          对于高吞吐量系统,随机方法是最好的,但如果您不想要随机性,该算法将完成这项工作。不要忘记在单元测试中对其进行测试!

          // setup
          int transactionCount = 0;
          int auditCount = 0;
          double targetAuditRatio = auditPercent/100.0;
          
          // start of processing
          transactionCount++;
          double actualAuditRatio = auditCount/transactionCount;
          
          if (actualAuditRatio < targetAuditRatio) {
              auditCount++;
              // do audit
          }
          // do processing
          

          【讨论】:

            【解决方案6】:

            如果您需要实时审核这些交易(在收到交易时),也许您可​​以使用随机数生成器来检查您是否需要审核交易。

            因此,例如,如果您要审核 50% 的交易,则对于收到的每笔交易,您将生成一个介于 0 和 1 之间的随机数,如果该数字大于 0.5,则审核该交易。

            虽然对于少量交易,这不起作用,但对于大量交易,这将使您非常接近所需的百分比。

            这比您最初的建议要好,因为 if 不允许一种方法来“欺骗”审计过程 - 如果您每第二次审计一次交易,这将允许不良交易溜走。

            另一种可能性是保持总交易的运行总数,因为这会改变需要审核的交易总数(根据您的百分比),您可以将交易输送到审核流程中。然而,这仍然会增加有人检测到该模式并规避审计的可能性。

            【讨论】:

              【解决方案7】:

              试试这个:

              1) 将审计百分比保留为小数。
              2) 对于每笔交易,关联一个随机数(介于 0 和 1 之间)
              3) 如果随机数小于百分比,则审计交易。

              【讨论】:

                【解决方案8】:

                为什么不随机做。对于每笔交易,选择一个介于 0 到 100 之间的随机数。如果该数字小于您的“百分比”,则审核该交易。如果这个数字大于你的“百分比”,那么不要。我不知道这是否满足您的要求,但在很长一段时间内,您将获得正确百分比的审核。

                如果您需要精确的“跳过 2,审核一,跳过 2 审核一”类型的算法,您可能会很幸运地适应 line-drawing algorithm

                【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-08-01
                • 2020-09-01
                • 2011-06-01
                • 2021-01-10
                • 2022-12-05
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多