Матрично-алгебраическая декомпозиция дизайна

Я смотрю на рефакторинг некоторого очень сложного кода, который является подсистемой проекта, который я имею на работе. Часть моего исследования этого кода заключается в том, что он невероятно сложен и содержит много входных данных, промежуточных значений и выходных данных в зависимости от некоторой основной бизнес-логики.

Я хочу перестроить этот код, чтобы его было проще поддерживать, а также выполнять его намного быстрее, поэтому для начала я попытался взглянуть на каждый из параметров и их зависимости друг от друга. Это привело к довольно большому и запутанному графу, и я хотел бы механизм для упрощения этого графа.

Некоторое время назад я наткнулся на метод в книге о разработке SOA под названием "Разложение матрицы", который использует матрицу выходных данных и зависимости, которые они имеют от входных данных, применяет некоторую форму матричной алгебры и может генерировать диаграммы бизнес-процессов для этих зависимостей.,

Я знаю, что есть веб-инструмент, доступный по адресу http://www.designdecomposition.com/ однако он ограничен числом зависимостей ввода / вывода, которые вы можете иметь. Я попытался найти алгоритмический источник для этого инструмента (так что я мог попытаться реализовать его самостоятельно без ограничения размера), однако мне не повезло.

Кто-нибудь знает подобную технику, которую я мог бы использовать? В настоящее время я даже рассматриваю вопрос о том, чтобы взять матрицу зависимостей и применить некоторые генетические алгоритмы, чтобы увидеть, может ли эволюция создать более простой рабочий процесс...

Ура,

Айдос

РЕДАКТИРОВАТЬ:

Я объясню мотивацию:

Исходный код был написан для системы, которая вычисляла все значения (около 60) каждый раз, когда пользователь выполнял операцию (добавление, удаление или изменение определенных свойств элемента). Этот код был написан более десяти лет назад и определенно показывает признаки старения - другие добавили в систему более сложные вычисления, и теперь мы получаем совершенно необоснованную производительность (до 2 минут до того, как управление возвращается пользователю). Было решено отделить расчеты от действий пользователя и предоставить кнопку для "пересчета" значений.

Моя проблема возникает из-за того, что происходит так много вычислений, и они основаны на предположении, что все необходимые данные будут доступны для их вычислений - теперь, когда я пытаюсь повторно реализовать вычисления, я продолжаю сталкиваться с проблемами, потому что у меня нет не получил результат для другого вычисления, на которое опирается этот расчет.

Здесь я хочу использовать метод матричной декомпозиции. Подход MD позволяет мне определить все входы и выходы и дает мне "самый простой" рабочий процесс, который я могу использовать для генерации всех выходов.

Затем я могу использовать этот "рабочий процесс", чтобы узнать приоритет вычислений, которые мне нужно выполнить, чтобы получить тот же результат без генерации каких-либо исключений. Он также показывает мне, какие части вычислительной системы я могу распараллелить и где будут точки ветвления и соединения (пока я не буду беспокоиться об этой части). На данный момент все, что у меня есть, - это безумно большая матрица с множеством зависимостей, которые я не знаю, с чего начать.

Я уточню из моего комментария немного больше:

Я не хочу использовать решение из процесса EA в реальной программе. Я хочу взять матрицу зависимостей и разложить ее на модули, которые затем буду кодировать вручную - это чисто вспомогательное средство проектирования - меня просто интересует, какие будут входы / выходы для этих модулей. В основном это представление о сложных взаимозависимостях между этими вычислениями, а также представление о приоритете.

Скажем, у меня A требует B и C. D требует A и E. F требует B, A и E, я хочу эффективно разделить проблемное пространство из сложного набора зависимостей в "рабочий процесс", который я могу исследовать, чтобы лучше понимание. Как только у меня появится это понимание, я смогу придумать лучший дизайн / реализацию, которая по-прежнему будет удобочитаемой для человека, поэтому для примера, который я знаю, мне нужно вычислить A, затем C, затем D, затем F.

-

Я знаю, что это выглядит немного странно, если вы посмотрите на сайт, на который я ссылаюсь, до того, как разложение на основе матрицы даст вам некоторое представление о том, о чем я думаю...

4 ответа

kquinn, если это часть кода, я думаю, он имеет в виду (я раньше работал там), то это уже решение черного ящика, которое не может понять ни один человек. Он не хочет сделать это более сложным, на самом деле менее. То, чего он пытается добиться, это целая куча взаимосвязанных вычислений.

В настоящее время происходит то, что всякий раз, когда что-то меняется, это лавина событий, которая вызывает целую кучу вычислений, что, в свою очередь, вызывает целую кучу новых событий, которые продолжаются, пока, наконец, не достигнет состояния равновесия.

Я предполагаю, что он хочет сделать, это найти зависимости для этих отдаленных вычислений и работать оттуда, чтобы их можно было переписать и найти способ выполнения вычислений ради этого, а не потому, что им это нужно.

Я не могу дать много советов в отношении упрощения графика, поскольку, к сожалению, у меня нет большого опыта в этом. Тем не менее, я бы начал искать те отдаленные вычисления, которые не имеют зависимостей, и просто перебирать график оттуда. Начните создавать новую платформу, которая включает в себя основную бизнес-логику каждого вычисления самым простым способом, и по ходу рефакторинг ерунды из нее.

Какой язык вы используете? Ваша проблема должна быть довольно легко смоделирована с использованием задач 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...)

Если черный ящик является линейным, вы можете обнаружить все коэффициенты, просто объединив множество векторов ввода и множество векторов вывода.

вы вводите 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

Мне было бы любопытно, сможете ли вы это сделать.

Я считаю, что проще понять код и переписать его, используя лучшие практики.

Если это, как вы говорите, "основная бизнес-логика", то вы действительно не хотите возиться с причудливыми декомпозициями и эволюционными алгоритмами, которые создают решение "черного ящика", которое никто в мире не понимает или не способен понять. модифицирование. Я был бы очень удивлен, если бы любой из этих методов действительно дал какой-либо полезный результат; человеческий мозг все еще непостижимо более способен, чем любая другая машина, на распутывание сложных отношений.

То, что вы хотите сделать, это традиционный рефакторинг: очистить отдельные процедуры, оптимизировать их и объединить их, где это возможно. Ваша цель - прояснить код, чтобы вашему преемнику не пришлось проходить тот же процесс.

Другие вопросы по тегам