Algorithm 从给出所需系数的数字数组中查找组合

Algorithm 从给出所需系数的数字数组中查找组合,algorithm,data-structures,Algorithm,Data Structures,请为此类任务推荐最佳算法或解决方案: 有几个带有小数的数组 a = [1.5, 2, 3, 4.5, 7, 10, ...(up to 100 numbers)] b = [5, 6, 8, 14, ...] c = [1, 2, 4, 6.25, 8.15 ...] (up to 7 arrays) 数组可以是任意长度,并包含不同的数字计数 需要从每个数组中选择一个数字,以使其乘积在给定范围内 例如,产品所需的数据应介于40和50之间。 解决方案可以是: a[2]*b[2]*c[1]=3*8

请为此类任务推荐最佳算法或解决方案:

有几个带有小数的数组

a = [1.5, 2, 3, 4.5, 7, 10, ...(up to 100 numbers)]
b = [5, 6, 8, 14, ...]
c = [1, 2, 4, 6.25, 8.15 ...] (up to 7 arrays)
数组可以是任意长度,并包含不同的数字计数

需要从每个数组中选择一个数字,以使其乘积在给定范围内

例如,产品所需的数据应介于40和50之间。 解决方案可以是:

  • a[2]*b[2]*c[1]=3*8*2=48
  • a[0]*b[3]*c[1]=1.5*14*2=42

  • 如果可以有多个解决方案(不同的组合),那么如何以最佳方式找到它们呢?

    这是可行的,但几乎不可行。这将需要使用各种策略反复组合成对的事物

    首先,如果您有两个不超过100个的数组,那么您可以创建一个包含所有对的数组,按升序或降序和排序,其中只有10000个

    接下来,我们可以使用来实现

    使用优先级队列,我们可以组合2个大小不超过10000的有序数组,以升序或降序输出总和,同时不跟踪超过10000个内容。怎样首先,我们创建如下数据结构:

    Create priority queue
    For every entry a of array A:
        Put (a, B[0], 0) into our queue using the product as a priority
    return a data structure which contains B and the priority queue
    
    If the priority queue is empty:
        We're done
    else:
        Take the first element of the queue
        if not at the end of B:
            insert (a, b[next_index], next_index) into the queue
        return that first element
    
    For each combination (in ascending order) from first 4:
        For each combination that lands in window from last 3:
            emit final combination
    
    while there is a next value and next value is large enough to fit in the window:
        Extract next value
        Add next value to end of window
    while first value is too large for the window:
        remove first value from the window
    
    现在我们可以得到如下值:

    Create priority queue
    For every entry a of array A:
        Put (a, B[0], 0) into our queue using the product as a priority
    return a data structure which contains B and the priority queue
    
    If the priority queue is empty:
        We're done
    else:
        Take the first element of the queue
        if not at the end of B:
            insert (a, b[next_index], next_index) into the queue
        return that first element
    
    For each combination (in ascending order) from first 4:
        For each combination that lands in window from last 3:
            emit final combination
    
    while there is a next value and next value is large enough to fit in the window:
        Extract next value
        Add next value to end of window
    while first value is too large for the window:
        remove first value from the window
    
    我们可以通过查看队列的第一个元素而不触及数据结构来查看它们

    此策略可以通过2个大小为10000的阵列进行数据流传输,总工作量仅为数十亿次操作

    好的,现在我们可以安排总是有7个数组。(有些可能只是微不足道的
    [1]
    )我们可以从以下暴力策略开始

    Combine the first 2 ascending.
    Combine the second 2 ascending.
    Combine the third 2 descending.
    Arrange the last descending.
    
    接下来,我们可以使用优先级队列合并策略,如下所示:

    Combine (first 2) with (second 2) ascending
    Combine (third 2) with last descending
    
    我们现在只需要发电机

    现在我们的战略是这样的:

    Create priority queue
    For every entry a of array A:
        Put (a, B[0], 0) into our queue using the product as a priority
    return a data structure which contains B and the priority queue
    
    If the priority queue is empty:
        We're done
    else:
        Take the first element of the queue
        if not at the end of B:
            insert (a, b[next_index], next_index) into the queue
        return that first element
    
    For each combination (in ascending order) from first 4:
        For each combination that lands in window from last 3:
            emit final combination
    
    while there is a next value and next value is large enough to fit in the window:
        Extract next value
        Add next value to end of window
    while first value is too large for the window:
        remove first value from the window
    
    但是我们怎么打开窗户呢?好吧,当前4个的组合上升时,最后3个必须进入的窗口下降。因此,调整窗口如下所示:

    Create priority queue
    For every entry a of array A:
        Put (a, B[0], 0) into our queue using the product as a priority
    return a data structure which contains B and the priority queue
    
    If the priority queue is empty:
        We're done
    else:
        Take the first element of the queue
        if not at the end of B:
            insert (a, b[next_index], next_index) into the queue
        return that first element
    
    For each combination (in ascending order) from first 4:
        For each combination that lands in window from last 3:
            emit final combination
    
    while there is a next value and next value is large enough to fit in the window:
        Extract next value
        Add next value to end of window
    while first value is too large for the window:
        remove first value from the window
    
    (可变大小的数组,如Python的
    列表
    ,可以在摊销
    O(1)
    中分别执行这两种操作。)

    因此,我们的实际完成方式是:

    For each combination (in ascending order) from first 4:
        adjust entries in window from last 3
        For each in window from last 3:
            emit final combination
    

    这有几十亿个操作加上
    O(答案数)
    的固定开销,以实际发出组合。这包括一系列数据结构,包含大约10k个项目,加上一个最大大小为100万个项目的窗口,最大内存使用量为数百MB。

    到目前为止,您尝试/研究了哪些内容?分享你的想法/发现/代码。这项任务背后的真正问题是什么?也许有更好的方法来解决最初的问题。此外,它还可以帮助对数据添加一些约束,如
    number>=1
    等等。由于您没有发布暴力实现,我们只能猜测您是否考虑了其中的任何优化。这里有一些初步的想法:由于要排序的值(每个数组),您可以提前消除很多情况。还考虑到每个数组的最小值和最大值可用于跳过许多情况…:(同时从每个数组中提取一个因子以确保每个数组包含1可能是有用的)@YD1m在问题中,您提供的所有输入数组都已排序。输入数组是否始终进行排序?@YD1m对于每个所需范围仅为一个解决方案,或者必须计算或显示所有可能的解决方案?