设计用于检查组合的算法

时间:2018-07-21 18:01:35

标签: algorithm performance loops matching

我的日常工作遇到严重的性能问题,我认为我无法改进算法;所以我是gonnga向您解释要解决的问题以及我们拥有的算法,也许您还有其他一些想法可以更好地解决问题。

所以我们要解决的问题是:

  • 有一组规则,约120.000条规则。
  • 每个规则都有一组代码组合。代码基本上是字符串。因此,每个规则有8种组合。组合示例:TTAAT; ZZUHH; GGZZU; WWOOF; SSJJW; FFFOLL
  • 有一组对象,约800个对象。
  • 每个对象都有一组〜200个代码。

如果对象中完全包含至少一个代码组合,则必须对每个规则进行检查。这意味着=>

loop in Rules
   Loop in Combinations of the rule
       Loop in Objects
            every code of the combination found in the Object? => create relationship rule/object and continue with the next object
       end of loop
   end of loop
end of loop

例如,如果我们具有包含以下两个代码组合的规则:HHGGT;佐夫 假设我们有一个对象,其代码如下:HHGGT; DHZZU; OIJUH; ZHGTF; HHGGT ; JUHZT; ZZUUF ; TGRFE; UHZGT; FCDXS

然后,我们在对象和规则之间创建关系,因为规则组合的每个代码都包含在对象的代码中=>这就是算法要做的。

如您所见,这非常昂贵,因为在最坏的情况下,我们需要120.000 x 8 x 800 = 7.5亿次。

这是实际问题的简化方案;实际上,我们在循环中执行的操作稍微复杂一些,这就是为什么我们必须以某种方式减少这种情况。

我试图思考一个解决方案,但是我没有任何想法!

您在这里看到错了吗?

最诚挚的问候,谢谢您的宝贵时间:)

1 个答案:

答案 0 :(得分:0)

如果我正确理解(在python中),这样的事情可能会更好:

RULES = [
    ['abc', 'def',], 
    ['aaa', 'sfd',],
    ['xyy', 'eff',]]

OBJECTS = [
    ('rrr', 'abc', 'www', 'def'), 
    ('pqs', 'llq', 'aaa', 'sdr'), 
    ('xyy', 'hjk', 'fed', 'eff'), 
    ('pnn', 'rrr', 'mmm', 'qsq')  
]   


MapOfCodesToObjects = {}
for obj in OBJECTS:
    for code in obj: 
            if (code in MapOfCodesToObjects):
                    MapOfCodesToObjects[code].add(obj)
            else:   
                    MapOfCodesToObjects[code] = set({obj})

RELATIONS = []

for rule in RULES:
    if (len(rule) == 0):
            continue
    if (rule[0] in MapOfCodesToObjects):
            ValidObjects = MapOfCodesToObjects[rule[0]]
    else:   
            continue
    for i in range(1, len(rule)):
            if (rule[i] in MapOfCodesToObjects):
                    codeObjects = MapOfCodesToObjects[rule[i]]
            else:   
                    ValidObjects = set() 
                    break   
            ValidObjects = ValidObjects.intersection(codeObjects)
            if (len(ValidObjects) == 0):
                    break   
    for vo in ValidObjects:
            RELATIONS.append((rule, vo))


for R in RELATIONS:
    print(R)

首先,您将代码映射到对象。如果每个对象平均有nObj个对象和nCodePerObj个代码,则花费O(nObj*nCodePerObj * log(nObj*nCodePerObj)

接下来,您将遍历规则,并在构建的映射中查找每个规则中的每个代码。如果规则中的每个代码都存在某个对象,即该规则中的每个代码都在对象的已设置交集中,则存在某种关系。由于哈希查找的平均时间复杂度为O(1),而集合交集的时间复杂度为O(min of the lengths of the 2 sets),因此将花费O(nRule * nCodePerRule * nObjectsPerCode),(请注意,这是nObjectsPerCode而不是nCodePerObj,当使用一个代码时,性能会变差包含在许多对象中。)