如何对部分可重用算法进行适当的设计/架构

How to make proper design/architecture of partially reusable algorithm?

本文关键字:架构 算法      更新时间:2023-10-16

我很抱歉解释这么长,但这是正确理解所必需的。

我正在研究工业任务的计算机视觉算法。计算机视觉算法往往非常复杂。通常它们涉及调用几十个(至少)更简单的算法(这些算法也不简单)。这些调用形成一定的层次结构:较大的任务调用一些较小的任务,这些任务再调用更小的任务,以此类推。

让我们以典型的计算机视觉任务为例:在一定条件下在图像中找到对象。这是一项应该在几十个不同的应用程序中执行的任务。每个应用程序都有自己的一组条件,因此不可能创建适用于所有应用程序的单一算法。但它们非常相似。通常替换一个或两个较低级别的函数就足够了。例如:使用不同的方法检测图像中的兴趣点。

问题来了:对于每个新应用程序,我必须从一个现有应用程序复制整个代码并调整相关部分,这是一种不好的做法。我试图通过创建可以在所有应用程序中使用而不改变代码本身的算法系统来消除这些重复。以下是系统必须处理的问题列表(至少是我目前发现的问题):

1)提供给主算法的参数应该能够设置系统内部的"算法流",即它们决定使用什么低级算法以及如何使用

2)执行相同任务的不同子算法可能需要不同的输入。一个可能需要整型数组,另一个可能需要一对双精度数,等等……更高层次的算法应该不介意用一个子算法替换另一个子算法。这意味着它们不应该知道它们接收并传递给子算法的参数是什么。子算法的输出也是如此。如果使用不同的子算法组合,它可能会有所不同

3)系统必须具有可扩展性。如果新的子算法可用(例如:另一种寻找兴趣点的方法),系统应该能够调用它。我明白,在这一点上,变化可能是不可避免的,但我希望将它们保持在最低限度。在任何情况下,系统都应该能够以同样的方式处理之前的参数集。

4)系统必须可调试。系统的最终用户应该有合理的方式来转储关于他的系统中的"算法流"的调试信息,以便算法开发人员能够重新创建这种情况。考虑到需求(3),它并不是那么微不足道。

5)应该有合理的方法对算法流进行完整性检查。

6)我不打算抛出异常,但应该有合理的方法来返回每个算法的成功/失败状态。由于需求(3),这也不容易。

7)这一点更像是"有"而不是"必须",但它可能很重要。有些计算可能由多个子算法执行。例如,多个不同的任务可能需要(也可能不需要)计算图像中的梯度。最好有一个存储这些计算结果的选项,以便以后重用它们。

我创造了某种解决方案,但它远非好。你有什么建议吗?

使用语言:c++

谢谢你

我会使用一些经过验证的设计模式。

使用策略模式来表示您可能希望替换的算法。

使用工厂根据一些输入参数或运行时上下文实例化不同的算法(策略)实例——我是原型工厂的粉丝,在原型工厂中,您在某些查找表中拥有每个对象的"惰性"实例,并且基于传入的键,您可以请求所需对象的克隆。我喜欢它主要是因为它最容易扩展——你甚至可以在运行时向这样的工厂添加新的配置原型实例。

请注意,相同的"策略"模型并不一定要服务于所有事情——听起来你可能有一些高级/模糊的操作,然后将低级/详细的操作组装或链接在一起。高级操作可以是一种抽象对象,而详细算法是更具体的策略实例。

至于各种算法的输入,如果不同算法之间的差异很大,你可以使用一个可扩展的对象,比如参数字典,这样每个算法就可以只使用它需要的参数,而忽略其他的操作参数。如果字典在操作期间是可修改的,这也将允许上游算法为下游算法添加参数。键值对很容易转储到调试器中的日志或视图中。

如果每个策略实例都有一个唯一的语义标识符,你可以很容易地调试实例化和链接在一起的算法。(我使用一个音频DSP库,它具有转储整个配置音频处理器链的描述的功能,这是非常方便的)。

如果你使用一个具有策略模式和可扩展参数的系统,你还应该能够将共享算法从特定于应用程序的算法中分离出来,但仍然有相同的基本框架来实例化和运行它们。

hth

我将假设您是一个具有良好领域知识的称职的OO程序员,并且您的问题更多地是关于软件组件(实现算法)的更高层次的组织,而不是OO通常提供的。

@orpheist提到的模式非常有意义。考虑他们。它们不会解决你列出的所有问题。你还应该考虑以下几点:

  • 算法将以什么形式访问数据?
  • 您是否需要适配器将一个组件连接到另一个组件?
  • 是将数据传递给组件还是组件传递给数据?
  • 您是否希望组装一个管道或一组组件来构建更高的管道,然后可以应用于数据?
  • 您是否需要一种语言(XML、DSL)来表达连接并允许简单的实验?
  • 性能已经是一个主要问题了吗,或者在这个阶段你能负担得起更多的解释性技术吗?
我认为你需要改进你的一些问题,并提供一些更具体的细节。我也认为你的问题更适合程序员。