我有一个1D的权重数组,w和一个与w形状相同的容量c数组。我需要找到最小的索引数组,这样当w被这些索引分割时,分裂数组的cumsum小于c中的相应容量。 给定一系列权重和容量如下:
w = [1,2,3,4,5,6]; c = [3, 12, 7, 6, 12]
我需要找到最少数量的指数' i'这样分裂阵列的cumsum小于c中的相应容量。在这种情况下,
i = [2, 3, 5]
由i形成的w分裂阵列的cumsum是
[1, 1+2, 1+2+3, 4, 5, 5+6]
每个元素明显小于c。累积和计算为给定here。
所需指数的近似值也很好。但是cumsums应该严格地小于c中的相应元素。
w是一个非常大的数组(大小为100000个元素)。我需要一个矢量化的解决方案才能提高效率。如前所述,只要毛囊小于c
,近似就很好这是我尝试过的。我假设整个c矩阵只是重复多次的一个元素(我试图首先解决一个更简单的情况,然后增加复杂性)。在这种情况下,我只需要确保每个拆分数组的总和必须小于给定值(有点类似于bin打包)。我发现索引如下。
weights = np.random.random_integers(1, 20, size=(20))
capacity = 100
# Find cumulative sums and divide by capacity. This gives an approximation of indices. All elements in first
# split array would have values between 0 and 1. Those in second array would have elements between 1 and 2,
# and so on. When ever the integer part changes, a new split array would be formed. Find indices from this.
# After taking the ceiling value of all elements, elements between 0 and 1 would become 1, elements between
# 1 and 2 become 2 and so on. The place where the elements change give the indices. Take diff to find the
# boundary (of change).
indices = np.diff(np.ceil(np.cumsum(weights[i]) / self.sleigh_capacity))
# 0s represent repeated elements, 1s represent values where values change. Find the indices
indices = np.where(indices != 0)[0] + 1
这给了我指数。需要注意的一点是,这可能会给我错误的指数,因为累计金额是从头开始计算的。 也就是说,[1,2,3,2,3]的cumsum是[1,2,6,8,9]。现在,如果我的容量是5。 将cumsum除以5并取ceil给出[1,1,2,2,2],这对应于[1,4]的分裂指数。但实际的分裂指数是[1,3,4]。我通过降低容量来处理这个问题。也就是说,如果我的实际容量为5,我将其视为4,然后执行上述操作(值4是纯粹的猜测。为了更安全,我可能会进一步降低容量)。< / p>
但是我无法将此方法扩展到容量变化的情况。也就是说,如果我有一个容量数组形状(1,5),那么我将不得不使用不同的方法,因为这种方法不起作用。
答案 0 :(得分:1)
w = [1,2,3,1,6,6]; c = [1,3,5, 1, 6, 12]
唯一的解决方案是
i=[2,3,4,5]
贪婪的解决方案(我的理解是采取直到你不能采取)
以2开始,得到[1,2]&lt; c中= [1,1 + 2]。 但是,如果下一次拆分为4(因为贪婪的解决方案导致,你会遇到问题,因为没有什么能满足1)。我们应该把它拆分为2和3。
我建议使用回溯来回顾这种情况,但是运行时间可能会失控。 100k的限制似乎暗示了最坏的线性解决方案或nlogn解决方案。我有关于如何使用动态编程实现这一点的想法,但仍然在弄清楚一些具体细节。希望更新,或在一段时间后丢弃答案。 :)