搜索算法:产品背包问题,目标是找到高于某一特定阈值的最低产品?

huangapple go评论64阅读模式
英文:

Searching Algorithm: Product Knapsack Problem with goal to find lowest product above a certain threshold?

问题

我正在寻找一些具有算法知识的人,他们可以帮助我解决这个问题。

我目前正在使用Java编写一个受限制的树搜索算法,我想要拥有一定数量的叶子节点,这个数量略大于给定的阈值T。

我将这个问题(很可能是NP完全问题)简化为以下形式:

问题

输入:一个阈值T,以及一个条目列表L = [e1, e2, ..., en],对于每个ei(其中1 <= i <= n),都有一个定义的任意最大权重wMaxi和最小权重wMini = 1。 (wMax_i >= wMin_i)

输出:一组权重wi,使得:

  • wMaxi >= wi >= wMini = 1
  • 权重**wi**的乘积大于阈值(W > T
  • 权重**wi**的乘积尽可能小,或者如果不可能的话,线性受限于T(W在O(T) / W < k * T

注意

  • 这里的所有数字都是整数。
  • 总是成立的,wMaxi的乘积Wmax >> T
  • 最好找到一个解,其中wi均匀分布,意味着我宁愿有[2,2,2,2 ...]而不是[4,1,4,1, ...],只要它是线性受限的,甚至可以优于找到最小可能的W。

当我尝试使用浮点数定义此问题时,我尝试近似解决方案:每个条目都能够具有**ceil(logn(T))**的权重,但是这种近似并不适用,因为最大权重分布不均匀。

此外,我阅读了一些关于解决乘积背包问题的文章,但它们主要关注实现最大权重。

我也不太确定这个问题是否可以简化为背包问题,因为阈值处理起来相当棘手,而且我涉及到乘积。

编辑:
最后,我通过迭代均匀增加权重来使用蛮力法解决了它,直到超过T。

编辑:

示例数据:

  • 条目:[e1 ,e2 , e3 , e4]
  • 最大权重分别为:[3,3,2,5]
  • 阈值:T = 15

解决方案(最接近阈值):

  • e1 = 1, e2 = 3, e2 = 1, e4 = 5 (乘积 15
  • e1 = 3, e2 = 1, e2 = 1, e4 = 5 (乘积 15

解决方案(尽可能平衡,同时也接近阈值):

  • e1 = 2, e2 = 2, e3 = 2, e4 = 2 (乘积 16
英文:

I'm looking for people with some algorithmic knowledge who can help me out with this.

I'm currently programming a constrained tree search in java, where I want to have a certain amount of leaf nodes that is just bigger than a given threshold T.

I'm boiling down the problem (which is most likely NP complete) to this:

Problem

> Input: a threshold T, and a List of entries L = [e<sub>1</sub>, e<sub>2</sub>, ..., e<sub>n</sub>], where for every e<sub>i</sub> (where 1 &lt;= i &lt;= n) there is a defined arbitrary maximum weight wMax<sub>i</sub> and a minimum weight wMin<sub>i</sub> = 1. (wMax_i &gt;= wMin_i)

> Output: a choice of weights w<sub>i</sub>, so that:
>
> - wMax<sub>i</sub> &gt;= w<sub>i</sub> &gt;= wMin<sub>i</sub> = 1
> - the product W of w<sub>i</sub> is greater than threshold (W &gt; T)
> - the product of w<sub>i</sub> is lowest possible or if not possible is linearly constrained in T (W is in O(T) / W &lt; k * T)

Notes

  • all numbers are integers here
  • it will always be true that the product of wMax<sub>i</sub> W<sub>max</sub> &gt;&gt; T
  • it would be highly preferable to find a solution where the w<sub>i</sub> are evenly distributed, meaning that I would rather have [2,2,2,2 ...] than [4,1,4,1, ...], this would be even more preferred over finding a solution with lowest possible W as long as it's linearly constrained.

I tried to approximate the solution when defining this problem with float numbers: every entry would be able to have a weight of ceil(log<sub>n</sub>(T)) but this approximation doesn't work as the max weights are distributed quite unevenly.

Furthermore I read some articles on solving the product knapsack problem, but they were interested with achieving a max weight.

I'm also not so sure if this problem can be reduced to the knapsack problem, as the threshold is quite tricky to handle and I deal with products.

Edit:
I ended up brute forcing it by iteratively and evenly increasing weights until I'm above T.

Edit:

Example data:

  • entries: [e<sup>1</sup> ,e<sup>2</sup> , e<sup>3</sup> , e<sup>4</sup>]
  • weight<sub>max</sub> respectively: [3,3,2,5]
  • Threshold: T = 15

Solution (nearest Threshold):

  • e1 = 1, e2 = 3, e2=1, e4 = 5 (Product 15)
  • e1 = 3, e2 = 1, e2=1, e4 = 5 (Product 15)

Solution (as balanced as possible, while also near):

  • e1 = 2, e2 = 2, e3 = 2, e4 = 2 (Product 16)

答案1

得分: 2

我有一个类似于你的暴力算法思路的算法。

通过迭代地均匀增加权重,直到我超过了T。

让我们这样做,但使用二分查找代替。算法大致如下。

  1. 按**wMaxi**排序。
  2. f(x)定义为wi的乘积,其中wi = min(wMaxi, x)。关于如何计算f(x),请参见下文。
  3. 二分查找以找到k,其中f(k) <= Tf(k+1) > T
  4. 找到最佳的i来将列表分割为kk+1。所以如果j < i,则wj = min(wMaxi, k),如果j >= i,则wj = k+1。我们可以使用线性或二分搜索来找到i,使得产品略高于T

要计算f(x),一个简单的解决方案就足够了。但是我们还可以计算前缀乘积pi,二分查找i,其中wMaxi < xwMaxi+1 >= x。然后,f(x)等于pi加上剩余元素的数量的x的幂次方(注意防止一次性错误)。

该产品小于2 * T。还要注意,使用此算法,问题(其中产品不是最小化,但权重的方差/标准差最小化)不是NP完全问题。

英文:

I have an algorithm similar to your brute force idea.
> brute forcing it by iteratively and evenly increasing weights until I'm above T.

Let's do this, but using binary search instead. The algorithms goes something like this.

  1. Sort by wMax<sub>i</sub>
  2. Define f(x) as the product of w<sub>i</sub> where w<sub>i</sub> = min(wMax<sub>i</sub>, x). See below on how to compute f(x)
  3. Binary search to find k where f(k) <= T and f(k+1) > T
  4. Find the optimal i to "split" the list into k and k+1. So w<sub>j</sub> = min(wMax<sub>i</sub>, k) if j < i, and w<sub>j</sub> = k+1 if j >= i. We can to find i such that the product is just above T with either linear or binary search

To compute f(x), a naive solution would suffice. But we can also compute the prefix product p<sub>i</sub>, binary search for i where wMax<sub>i</sub> < x and wMax<sub>i+1</sub> >= x. Then f(x) is equal to p<sub>i</sub> plus x to the power of the number of elements left (watch out for off by 1 error).

The product is less than 2 * T. Also note that with this algorithm, the problem (where the product is not minimized but the variance/standard deviation of the weights is minimized) is not NP complete.

huangapple
  • 本文由 发表于 2023年6月19日 08:04:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502953.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定