假设 A
、B
和 C
是三个数组,每个数组都包含 N
个数字:
A = a[0], a[1], a[2], ..., a[N-1]
B = b[0], b[1], b[2], ..., b[N-1]
C = c[0], c[1], c[3], ..., c[N-1]
我想从数组 A 和数组 B 中选择最好的 k= a[i]+b[i] ,而不是 a[i]+b[i]。
乍一看,这似乎很简单,但我考虑得越多,它就变得越复杂。
最终我要在 Python 中实现此算法,但现阶段我只是试图了解如何编写高效的算法。
示例
为了澄清问题,算法的输入包括三个 N x 1 数组 A、B 和 C,以及一个整数值 k。其期望的输出是两个 k x 1 的索引列表,定义了来自 A、B(和C)的价值最大化的元素组合。
例如,假设 k=2,N=4, 则
A = a[0], a[1], a[2], a[3] = 3, 1, 1, 0
B = b[0], b[1], b[2], b[3] = 1, 3, 0, 1
C = c[0], c[1], c[2], c[3] = 4, 4, 3, 2
即使在这个简单的例子中,有许多可能的组合。例如,如果从
A
选择元素i = 0,2
,并从B
选择元素j = 1,3
,那么总值将是a [0] + a [2] + b [1] + b [3] = 8
。另一方面,如果从
A
和B
中选择元素i = 0,1
和j = 0,1
,则应用特殊扭曲:总值不是a [0] + a [1] + b [0] + b [1]
,而是由c [0] + c [1] = 8
给出。在这个例子中,最大化总值的元素组合由
A
中的i = 0,2
元素和B
中的j = 1,2
元素给出。这产生了一个总价值为a [0] + b [1] + c [2] = 9
,可以验证它比任何其他组合都更大。答案比较
以下是对三个提交的解决方案的快速比较。首先,我检查了它们所有的结果,它们都给出了预期的结果。顺便说一句,它们都不要求
C
的元素弱大于A
和B
中相应元素的总和,因此我在我的性能评估中取消了这个假设。import numpy as np
from utils import tic, toc # simple wrapper to time.perf_counter()
k, N = 10, 1000
A = list(np.random.random_sample([N]))
B = list(np.random.random_sample([N]))
C = list(np.random.random_sample([N]))
tic()
print(optimal_choices(k, A, B, C)) # solution by btilly
toc()
tic()
print(maxPicks(A.copy(), B.copy(), C.copy(), k)) # solution by Eric T-M
toc()
tic()
print(maxSum(A, B, C, k)) # solution by Alain T.
toc()
我尝试了各种不同的k
和N
的组合,似乎@btilly的算法只要k
很小,就能很好地处理大规模数据N
。相反地,当k
相对于N
很大时,@Alain-T.的算法表现得更好。总体而言,@Eric-T-M的算法表现最好,在k
和N
的扩展性方面都表现良好。
小规模问题: k = 10 and N = 500
- btilly's算法: 0.49秒
- Eric T-M's算法: 0.00秒
- Alain T.'s算法: 0.52秒
小k,大N: k = 10 and N = 1000
- btilly's算法: 0.89秒
- Eric T-M's算法: 0.00秒
- Alain T.'s算法: 1.99秒
大k,小N: k = 80 and N = 100
- btilly's算法: 1.54秒
- Eric T-M's算法: 0.00秒
- Alain T.'s算法: 0.09秒
中等规模问题: k = 50 and N = 1000
- btilly's算法: 13.01秒
- Eric T-M's算法: 0.00秒
- Alain T.'s算法: 8.55秒
大规模问题1: k = 10 and N = 1_000_000
- Eric T-M's算法: 1.03秒
大规模问题2: k = 1_000 and N = 100_000
- Eric T-M's算法: 10.22秒
(为了进行基准测试,我删除了Alain T.代码中的排序操作,使之具有可比性。)
c
是否始终大于元素a
和b
对应元素之和? - gionnic
中的元素弱大于其对应的a
和b
元素之和(抱歉来回反复,我在@wildplasser的下面评论中稍微有点困惑) - Bob