【问题标题】:How to calculate closest total price from item prices collection with multiple items如何从包含多个项目的项目价格集合中计算最接近的总价格
【发布时间】:2021-08-19 04:26:57
【问题描述】:

给定供应商的一组价格,我想计算出与总价值最接近的匹配项目集。

IE。匹配的总价值是 5 美元,我有一个来自 MongoDB 的价目表如下

val items = List(0.05, 0.06, 1.0, 2.0)

我如何计算出可以提供 5 美元的物品集?这些物品可以复制以匹配价格。

我的想法是使用 Stream 来评估价目表并创建排列和匹配,准确度为 0.01 美元,但我不知道该怎么做?

另一个想法是从 MongoDB 编写一个聚合来提供排列,然后按总价排序并选择最接近的一个

更新:

所以我现在使用以下方法从数据库中抽样产品:

db.getCollection("shop-items").aggregate([
    {
        $bucketAuto: {
              groupBy: "$prices.avg",
              buckets: 50,
              output: {
                "items" : {
                    $push: "$$ROOT"
                },
               "count": { $sum: 1 },
              }
          }
    },
    {$addFields: {"startField": {$floor :{$multiply: [ { $rand: {} }, "$count"]}}}},
    {$project : { _id: 0, items: {$slice: ["$items", "$startField", 20]}}},
    {$unwind: "$items"}
])

这会产生大约 650 的项目,但仍会导致我需要计算的 650! 排列

【问题讨论】:

  • 我想要尽可能少的项目,现在我正在优化数据库以减少排列计数,但我认为在 LazyList 上使用 .permutations 可以解决问题,但 LazyList 不是排序,我不明白排列的创建顺序是什么
  • @jwvh 如果有平局之类的,我可以选择任何一个,所以我希望第一个匹配价格
  • 我尝试了this 但是这加载了所有 5000!排列到内存中,我可能在代码上犯了错误?

标签: mongodb scala stream permutation


【解决方案1】:

这是一道算法题。使用数据库生成排列听起来效率不高。您正在寻找的是带有记忆功能的Knapsack solution。基本上,你需要解决ar(n) = minimum number items to get total sum n (with buffer of $0.01, if needed)。算法草图将是:

Memoized array ar[500], where ar[y] = minimum number of items to match $(y/100).
All elements are initalized to infinite/very large value.

val items = [5, 6, 100, 200]

Initialize / populate: ar[0] = 0; items.forEach(ar[_] = 1);

while ($ar[500] is not populated) {
  for (y where ar[y] is populated) {
     items.forEach( item => ar[y + item] = min(ar[y + item], ar[y] + 1);
  }
}

这将导致 O(n * m) 的上限复杂度,其中 n 是可能结果的总数(此处为 500),m 是不同项目价格的总数,可能是一个常数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 2014-04-03
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2022-11-15
    相关资源
    最近更新 更多