寻找最佳维度组合的算法

Algorithm to find best dimensions combination

我正在寻找一种算法来找到实现预期结果的最佳维度组合。

以下为例:

|   A    |    B   |   C   |  y  |
|--------|--------|-------|-----|
| dog    | house1 | green | 30  |
| dog    | house1 | blue  | 15  |
| cat    | house1 | green | 20  |
| cat    | house2 | red   |  5  |
| turtle | house3 | green | 50  |

A、B、C 为实测尺寸。 y是测量结果。

如果我想获得满足 y >= 50 的所有维度组合,那么结果将是:

turtle, house3, green
turtle, any,    green
turtle, house3, any
turtle, any,    any
any,    house3, green
any,    house3, any
any,    any,    green
any,    house1, green
any,    house1, any

也许这是一个简单的问题,但我试图根据 O(n) 找出最佳解决方案,但我没有找到它。

从包含 (any, any, ..., any), 0 的工作队列开始。该队列的元素将成对,由一个组合和左侧的一些元素组成,这些元素不能从 any 改变(这很快就会变得更有意义)。直到工作队列为空,从中取出一个元素并计算相应的总和。如果它不符合阈值,则丢弃它。否则,将其报告为寻求的组合之一。对于每个可以更改的 any,对于该列中的每个值,将由当前值和 any 替换为该值的组合排入队列,索引锁定所有先前的 any值。

考虑到对输出敏感的边界,这在最优的多项式因子内(通常,可以有指数级的多种组合)。

在Python 3:

def overthreshold(data, threshold):
    queue = [(('any',) * len(data[0][0]), 0)]
    for combination, begin in queue:
        if sum(row[1] for row in data
               if all(x in {'any', y}
                      for x, y in zip(combination, row[0]))) < threshold:
            continue
        yield combination
        for i in range(begin, len(combination)):
            if combination[i] == 'any':
                queue.extend((combination[:i] + (x,) + combination[i+1:], i + 1)
                             for x in {row[0][i] for row in data})


def demo():
    data = [
        (('dog',    'house1', 'green'), 30),
        (('dog',    'house1', 'blue'),  15),
        (('cat',    'house1', 'green'), 20),
        (('cat',    'house2', 'red'),    5),
        (('turtle', 'house3', 'green'), 50),
    ]
    for combination in overthreshold(data, 50):
        print(combination)