英文:
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 <= i <= n) there is a defined arbitrary maximum weight wMax<sub>i</sub> and a minimum weight wMin<sub>i</sub> = 1. (wMax_i >= wMin_i)
> Output: a choice of weights w<sub>i</sub>, so that:
>
> - wMax<sub>i</sub> >= w<sub>i</sub> >= wMin<sub>i</sub> = 1
> - the product W of w<sub>i</sub> is greater than threshold (W > 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 < 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> >> 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。
让我们这样做,但使用二分查找代替。算法大致如下。
- 按**wMaxi**排序。
- 将
f(x)
定义为wi的乘积,其中wi = min(wMaxi, x)。关于如何计算f(x)
,请参见下文。 - 二分查找以找到k,其中f(k) <= T 且 f(k+1) > T。
- 找到最佳的i来将列表分割为k和k+1。所以如果j < i,则wj = min(wMaxi, k),如果j >= i,则wj = k+1。我们可以使用线性或二分搜索来找到i,使得产品略高于T。
要计算f(x)
,一个简单的解决方案就足够了。但是我们还可以计算前缀乘积pi,二分查找i,其中wMaxi < x 且 wMaxi+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.
- Sort by wMax<sub>i</sub>
- 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 computef(x)
- Binary search to find k where f(k) <= T and f(k+1) > T
- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论