3

在当前项目中,我们需要在几乎完全连接的图中找到最便宜的路径,每个顶点对可以包含很多边。

我们开发了一个包含函数的插件

  1. 对于特殊遍历,此图可在执行时降低相似路径的重复出现率TRAVERSE。我们将其称为search()
  2. 用于从此类遍历的结果中特别有效地提取所需信息。我们将其称为extract()
  3. N用于根据目标参数提取最佳记录而无需昂贵的成本ORDER BY。我们将其称为best()

但是结果查询在完整数据上的性能仍然不理想。

所以我们决定修改search()函数,以便它可以首先观察最佳边缘,并通过使用函数的当前状态来修剪导致绝对不希望的结果的路径best()
整体解决方案实际上是Branch and Bound 方法的灵活实现

结果查询(省略extract()步骤)应如下所示

SELECT best(path, <limit>) FROM (
   TRAVERSE search(<params>) FROM #<starting_point>
   WHILE <conditions on intermediate vertixes>
  ) WHERE <conditions on result elements> 

WHILE这种形式是非常需要的,因此我们可以根据当前任务调整条件WHERE。该path字段是通过search()包含所有信息best()以继续生成的。

问题是best()函数严格在search()函数之后执行,因此search()不能根据已经评估的结果修剪非最佳分支best()

所以问题是:
有没有一种方法可以TRAVERSE一步一步地处理结果SELECT,就像旧路径在TRAVERSE使用 withsearch()处理的早期路径之后SELECT一样best()

4

1 回答 1

2

在这种情况下,查询执行将被流式传输。如果你添加一个

 System.out.println()

或者你在你的函数中放置一个断点,你会看到调用序列将是

search
best
search
best
search
...

您可以使用 ThreadLocal 对象http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html

存储一些上下文数据并在两个函数之间共享,或者您可以使用 OCommandContext(OSQLFunction.execute()方法中的最后一个参数来存储上下文信息。

您可以为此使用context.getVariable()和。context.setVariable()

两个查询(父查询和内部查询)的上下文不同,但它们应该通过父/子关系链接,因此您应该能够使用检索它们OCommandContext.getParent()

于 2015-11-23T16:09:57.233 回答