【问题标题】:Matrix-Algebra Design Decomposition矩阵代数设计分解
【发布时间】:2021-02-22 03:51:44
【问题描述】:

我正在考虑重构一些非常复杂的代码,这是我正在工作的项目的子系统。我对这段代码的部分检查是它非常复杂,并且包含大量输入、中间值和输出,具体取决于某些核心业务逻辑。

我想重新设计这段代码,使其更易于维护,并且执行得更快,所以一开始我一直在尝试查看每个参数以及它们之间的依赖关系。这导致了一个相当大且复杂的图,我想要一种简化此图的机制。

不久前,我在一本名为“矩阵设计分解”的关于 SOA 设计的书中遇到了一种技术,它使用输出矩阵及其对输入的依赖关系,应用某种形式的矩阵代数,并可以生成业务流程图对于那些依赖项。

我知道http://www.designdecomposition.com/ 提供了一个网络工具,但是它的输入/输出依赖项数量有限。我曾尝试四处寻找该工具的算法来源(因此我可以尝试自己实现它而不受大小限制),但是我没有运气。

有人知道我可以使用的类似技术吗?目前我什至正在考虑采用依赖矩阵并应用一些遗传算法来看看进化是否可以提出一个更简单的工作流程......

干杯,

爱多斯

编辑:

我会解释动机:

原始代码是为一个系统编写的,该系统在每次用户执行操作(添加、删除或修改项目的某些属性)时计算所有值(大约 60 个)。这段代码是十多年前写的,而且肯定显示出老化的迹象——其他人在系统中添加了更复杂的计算,现在我们得到了完全不合理的性能(在控制权返回给用户之前最多 2 分钟)。已决定将计算从用户操作中分离出来,并提供一个按钮来“重新计算”这些值。

出现我的问题是因为正在进行大量计算,并且它们基于这样的假设:所有必需的数据都可用于其计算 - 现在,当我尝试重新实现计算时,我一直遇到问题因为我没有得到这个计算所依赖的不同计算的结果。

这是我想使用矩阵分解方法的地方。 MD 方法允许我指定所有输入和输出,并为我提供可用于生成所有输出的“最简单”工作流程。

然后我可以使用这个“工作流程”来了解我需要执行的计算的优先级以获得相同的结果而不会产生任何异常。它还向我展示了我可以并行化计算系统的哪些部分以及分叉点和连接点将在哪里(我暂时不会担心那部分)。目前我只有一个非常大的矩阵,其中显示了许多依赖项,不知道从哪里开始。

我会从我的评论中详细说明:

我不想在实际程序中使用 EA 流程中的解决方案。我想获取依赖矩阵并将其分解为模块,然后我将手动编码——这纯粹是一种设计辅助——我只是对这些模块的输入/输出感兴趣。基本上是这些计算之间复杂的相互依赖关系的表示,以及一些优先级的概念。

假设我有 A 需要 B 和 C。D 需要 A 和 E。F 需要 B、A 和 E,我想有效地将​​问题空间从一组复杂的依赖项划分为我可以检查的“工作流”获得更好的理解。一旦我有了这种理解,我就可以提出一个更好的设计/实现,它仍然是人类可读的,所以对于这个例子,我知道我需要计算 A,然后是 C,然后是 D,​​然后是 F。

--

我知道这看起来有点奇怪,如果你看看我在基于矩阵的分解之前链接到的网站,应该会让你对我的想法有所了解......

【问题讨论】:

    标签: decomposition


    【解决方案1】:

    kquinn,如果这是我认为他所指的那段代码(我曾经在那里工作过),那么它已经是一个没有人能理解的黑盒解决方案。他不想让它变得更复杂,事实上更少。他试图实现的是一大堆相互关联的计算。

    目前发生的情况是,每当发生任何变化时,都会发生大量事件,导致大量计算触发,进而导致更多事件继续进行,直到最终达到平衡状态。

    我假设他想要做的是找到那些外围计算的依赖关系并从那里开始工作,以便可以重写它们并找到一种方法来进行计算,而不是因为它们需要。

    关于简化图表,我无法提供太多建议,因为不幸的是,这不是我有太多经验的事情。也就是说,我会开始寻找那些没有依赖关系的离群计算,然后从那里。开始构建一个新框架,以最简单的方式包含每个计算的核心业务逻辑,并在此过程中重构其中的废话。

    【讨论】:

    • 这绝对是您正在处理的代码。我想做的是想出一种不同的方法来做这件事。在不了解实际发生的事情以及发生的顺序的情况下,我试图将谚语推上山。
    • +1 因为您了解我要处理的内容,希望可以帮助详细说明我为什么要尝试这样做...
    【解决方案2】:

    如果如您所说,这是“核心业务逻辑”,那么您真的不想搞乱花哨的分解和进化算法,从而产生世界上没有人理解或理解的“黑盒”解决方案。是可以修改的。如果这些技术中的任何一种实际上产生了任何有用的结果,我会感到非常惊讶。人脑在处理复杂关系方面的能力仍然比任何机器都要强大得多。

    您要做的是传统重构:清理各个过程,精简它们并在可能的情况下合并它们。你的目标是让代码清晰,这样你的继任者就不必经历同样的过程。

    【讨论】:

    • 我已经详细阐述了文本,希望能阐明我在做什么以及为什么。
    【解决方案3】:

    您使用什么语言? 您的问题应该很容易使用 Java Executors 和 Future 任务建模,但您选择的平台上可能也有类似的框架可用?

    另外,如果我理解正确的话,您想为大量相互依赖的计算生成一条关键路径——这是动态完成的,还是您“只是”需要静态分析?

    关于算法解决方案;拿起最接近您的数值分析教科书的副本,并刷新您对奇异值分解和 LU 分解的记忆;我从头到尾猜测这就是您链接到的工具背后的原因。

    编辑:由于您使用的是 Java,我将简要概述一个建议:

    -> 使用线程池执行器轻松并行化所有计算

    -> 使用 Future 或 FutureTask:s 的对象映射解决相互依赖关系,即如果变量是 A、B 和 C,其中 A = B + C,请执行以下操作:

    static final Map<String, FutureTask<Integer>> mapping = ...
    static final ThreadPoolExecutor threadpool = ...
    FutureTask<Integer> a = new FutureTask<Integer>(new Callable<Integer>() {
                public Integer call() {
                   Integer b = mapping.get("B").get();
                   Integer c = mapping.get("C").get();
                   return b + c;
                }
            }
        );
    FutureTask<Integer> b = new FutureTask<Integer>(...);
    FutureTask<Integer> c = new FutureTask<Integer>(...);
    map.put("A", a);
    map.put("B", a);
    map.put("C", a);
    for ( FutureTask<Integer> task : map.values() )
          threadpool.execute(task);
    

    现在,如果我没有完全关闭(我很可能已经关闭了,因为我使用 Java 工作已经有一段时间了),你应该能够通过调整线程池大小来解决明显的死锁问题,或者使用一个不断增长的线程池。 (您仍然必须确保没有相互依赖的任务,例如如果 A = B + C 和 B = A + 1...)

    【讨论】:

    • 我正在使用 javjav。我很想将它并行化——但我认为我的问题比这更根本。我什至不知道有什么依赖关系(如果我想并行化,我需要能够识别分叉/合并点)。
    • 假设您可以使用比 1.5 更新的 JDK,请查看 java.util.concurrent 包。您不必对系统了解太多。我将编辑我的答案以给出一个快速而肮脏的建议:)
    • 当然是一种有趣的方法!我会试一试,我不确定它是否会起作用,因为我没有描述的问题的一部分是这不是一次性计算。如果您想象这些计算的链表,其中一些依赖于链表中的前一个和下一个元素 - 这使问题更加复杂。这种方法肯定能让我弄清楚我可以做哪些事情以及按什么顺序做!
    【解决方案4】:

    如果黑盒是线性的,您可以通过简单地连接许多输入向量和许多输出向量来发现所有系数。

    您有输入 x[i] 和输出 y[i],然后创建一个矩阵 Y,其列是 y[0]、y[1]、... y[n],以及一个矩阵 X,其列是 x[0], x[1], ..., x[n]。会有一个变换Y = T * X,那么你可以确定T = Y * inverse(X)。

    但既然你说它很复杂,我敢打赌它不是线性的。然后,如果您仍然想要一个通用框架,您可以使用这个因子图

    https://ieeexplore.ieee.org/document/910572

    如果你能做到这一点,我会很好奇。

    我认为更容易理解代码并使用最佳实践重写它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-19
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      相关资源
      最近更新 更多