Какую структуру данных выбрать для описания конфигуратора изделия?
Стоит задача написать программу-конфигуратор для выбора совместимых опций изделия (конкретно - производство измерительных приборов).
У каждой опции есть одно числовое значение из заданного диапазона. Опций много (до 100) и они между собой взаимосвязаны.
Пример исходного описания: Прибор ТИП1-ABCDEFG.
Взаимоисключающие опции: Если выбрана опция "А", то опции "D" и "G" выбрать нельзя. А если сначала выбрана опция "D", то нельзя выбрать опцию "A".
Зависимые опции: Если в опции "B" выбрано значение <100, то: для опции "G" допустимые значения от 200 до 300, опция "F" недоступна, и т.п.
Список опций и связи между ними будут периодически изменяться.
Программа будет написана на C++ или Python.
Посоветуйте:
Как представить и в какой структуре данных хранить описания взаимосвязей?
Может есть готовые open-source решения (не нашел)?
Для решения данной задачи можно использовать графы, где вершины будут представлять опции, а ребра - их взаимосвязи. Для хранения значений опций можно использовать ассоциативный массив (map) или хеш-таблицу (unordered_map), где ключом будет название опции, а значением - её числовое значение.
В каждой вершине графа можно хранить информацию о числовом диапазоне значений опции, а также о её зависимостях и взаимоисключениях с другими опциями. Для этого можно создать структуру данных, содержащую поля для хранения этой информации.
Для поиска совместимых опций можно использовать алгоритм поиска в глубину (DFS) или алгоритм поиска в ширину (BFS), обходя граф и проверяя совместимость каждой опции с уже выбранными опциями.
Относительно готовых open-source решений, можно рассмотреть использование библиотеки Boost Graph Library для работы с графами в C++. Также, существуют различные фреймворки для создания конфигураторов, например, OpenConfigurator или Configit. Однако, их использование может быть излишним для данной задачи, так как они могут быть слишком сложными и не подходить по требованиям проекта.
Непонятно зачем автор протегал это АЛГОРИТМАМИ. Тут вобщем-то имеет место обычная работа с формочкой.
Дизайнеры форм лабают это и не зная ваших умных абстракций. Просто пишут там хендлер на каждую радио-кнопку или на чек-боксик и в зависимости от действий - скрывают некоторые филды или подсвечивают.
Но если вам интересна теория, то такое поведение можно описать небольшим конечным автоматом. Или
в данной задаче несколькими конечными автоматами которые взаимосвязаны по реакции на переходы.
Гуглить можно по FSM (Finite State Machine) и библиотек по сям и питонам будет много.
Вообще данная задача еще не набрала критическую массу знаний чтоб кодить ее в автоматах.
Время потраченное на библиотеки и на привязку их к формам может быть слишком большим
и эффекта не будет. Будет разочарование.
Список опций и связи между ними будут периодически изменяться.
И чего, перелопачивать форму каждый раз при таких изменениях?
Хардкодить в форме приемлемо, когда зависимости прибиты гвоздями (а здесь зависимости приклеены на жвачку).
Насчёт внешнего представления я бы посмотрел в направлении XML, UML и т.п., можно поискать готовый код парсеров. Насчёт внутреннего представления мне понравился в комментариях вариант с графом.
И чего, перелопачивать форму каждый раз при таких изменениях?
Это только эксплуатация может показать. Иногда пересобрать форму может стоить
дешевле чем создавать отдельный язык графов или биндинга к форме.
XML, UML и т.п., можно поискать готовый код
А это вообще не имеет значения. Ценность DSL зависит от того как его понимает персонал который использует.
Может быть очень умный DSL который бесполезен и могут быть просто property-files которые очень
полезны.
Если бы не периодические изменения, можно было бы все сделать как mayton2019 предложил.
Но вот из-за того, что производство будет менять свои требования, и возник вопрос.
С учетом полученных ответов и идей вариант решения сейчас видится таким: Описание опций и взаимосвязей:
ListOptions – список, в котором хранятся опции и их параметры (позиция опции в коде заказа, ее описание, мин и макс значения параметра, флаг доступности) и ссылка на другой список ListRelatons, элементами которого являются зависимые и параметры накладываемых ограничений (мин и макс значения параметра, флаг доступности опции).
Для хранения списков можно использовать базу данных или Excel. Процедура конфигурирования:
Создается ListConfiguration, в который копируется ListOptions.
В интерфейсе пользователя настраиваются контролы (как mayton2019 предложил) в соответствии с текущими данными из ListConfiguration.
При выборе пользователем какой-либо опции алгоритм выполняет проход по списку ListRelatons для выбранной опции и применяет ограничения из него к параметрам опций в ListConfiguration. Если ранее выбранные параметры для опции выходят за обновленные параметры пользователю выдается сообщение.
Если выбраны не все позиции (продукт сконфигурирован не полностью), то переход на шаг 2.
Если есть комментарии/замечания таком по варианту – пишите, пожалуйста.