我有一个动物数据库,每个都有许多属性,范围从0到1--这些属性是大小,速度,毛羽等等。给定一组输入属性,以及每种属性的权重,我需要在动物组中找到“最接近”的匹配。有没有一种算法可以比O(n)时间更好地完成这项工作?
我特别想要做的是在游戏中通过遗传算法为“动物”找到合适的纹理,将它们与已经存在的动物相匹配。 “最接近”是指动物的属性差异的加权和最小。数据库和权重在应用程序启动时已知,因此可以投入大量时间来准备数据。
我已经根据用户偏好找到了字符串匹配和产品匹配的算法,但要么我找不到我正在寻找的东西,要么我不理解如何将这些概念重新应用到我的困境中。也许图论的世界有什么东西可以帮助我?
非常感谢任何帮助!
答案 0 :(得分:2)
您可以将项目视为高维空间中的点,并将它们全部插入到BSP树中,例如k-d tree。要使用属性权重,只需将它们乘以相应的坐标:(w1*x, w2*y, ...)
准备:(来自wikipedia,python代码)
def kdtree(point_list, depth=0):
if not point_list:
return None
# Select axis based on depth so that axis cycles through all valid values
k = len(point_list[0]) # assumes all points have the same dimension
axis = depth % k
# Sort point list and choose median as pivot element
point_list.sort(key=lambda point: point[axis])
median = len(point_list) // 2 # choose median
# Create node and construct subtrees
node = Node()
node.location = point_list[median]
node.left_child = kdtree(point_list[:median], depth + 1)
node.right_child = kdtree(point_list[median + 1:], depth + 1)
return node
搜索(来自gist,基于wikipedia algorithm)
# method of the Node-class
def closest_point(self, target, point, best=None):
if target is None:
return best
if best is None:
best = target
# consider the current node
if distance(target, point) < distance(best, point):
best = target
# search the near branch
best = self.child_near(point).closest_point(point, best)
# search the away branch - maybe
if self.distance_axis(point) < distance(best, point):
best = self.child_away(point).closest_point(target, point, best)
return best
了解详情:
答案 1 :(得分:1)
如果您可以花时间安排数据,则可以按分数对您的动物进行排序<(O(nlogn)
时间,但只进行一次),然后对分数应用二分搜索以在O(logn)
时间内找到最接近的匹配。
如果从SQL数据库中获取动物列表,则可以使用查询中的ASC
或DESC
关键字获取排序列表。
答案 2 :(得分:1)
您可以将此框架设置为最大权重匹配问题,但找到最小匹配的复杂性的下限将远远大于O(n)
。更像是O(n^3)
。
如果我必须尝试解决此问题,我会考虑根据权重成对匹配相同类型的属性(即,在输入'毛茸茸'属性和数据中的每个其他'毛茸茸'属性之间创建加权边缘设置,使用输入权重的某个因子和查询“毛茸茸”值与匹配的“毛茸茸”值之间的差异的倒数。此时,您可以将所有边缘合并到特定动物,并将边缘权重的总和作为匹配分数。
例如:
Monkey:
A1: 0.5
B1: 0.25
C1: 1.0
Giraffe:
A2: 0.2
C2: 0.9
D2: 0.1
Input query:
Ai: 0.4 with weight 0.8
Di: 0.2 with weight 0.25
所以我们创建了以下图表:
Ai --> A1 with weight 0.8 * 1/abs(0.5-0.4) (i.e., 8.0)
Ai --> A2 with weight 0.8 * 1/abs(0.2-0.4) (i.e., 4.0)
Di --> D2 with weight 0.25 * 1/abs(0.1-0.2) (i.e., 2.5)
然后我们用同一目标动物中的属性折叠所有边缘,以获得我们的候选人:
Monkey: 8.0
Giraffe: 4.0 + 2.5
它不漂亮,而且比O(n)
更糟糕(可能是m
的某个因素,其中m
是您要匹配的属性数量),但它可能是开始优化更好解决方案的起点。
答案 3 :(得分:0)
如何找到线性反转的数量?所以你有2个动物的线性数据集,你想通过对它们进行排序来找出它们有多么相似或不同。复杂性与合并排序相同。对于'n'个动物,你将计算nC2反转。