Подбор слагаемых для нужной суммы

22.01.24

Разработка - Математика и алгоритмы

Цель публикации - объяснение простого надежного метода, который вы можете применить на практике.

Скачать исходный код

Наименование Файл Версия Размер
Подбор слагаемых для нужной суммы:
.epf 9,95Kb
2
.epf 9,95Kb 2 Скачать

Это не единственная публикация по данной тематике на Инфостарт'е, но в тех, которые мне попались, предлагают "скачай файл и сам разбирайся", какой метод используется, рабочий ли он вообще. Не самый лучший вариант, когда нужно внедрить идею в ограниченные сроки.

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

 

Вводные данные:

На склад "Х" в течение месяца перемещают товары в различных количествах и имеющих разную себестоимость.

В конце месяца нужно сформировать такую выборку товаров для дальнейшего списания, в которую войдут товары со склада "Х", суммарная себестоимость которых будет максимально приближена к заданной сумме Х, но не будет её превышать.

Необходимо разработать механизм формирования такой выборки товаров.

У задачи "получить из набора слагаемых максимально приближенную к заданному числу сумму" есть несколько способов решения, её еще называют "Задача о сумме подмножеств" (см. статью на Википедии).

 

Рассмотрим один из способов:

N={х1, x2, x3, x4, x5...} - список слагаемых. В данном примере это себестоимость товаров.

R - Число, к которому стремится, не превышая, сумма слагаемых из списка N. 

 

Шаги решения:

1. Создать список F, первоначально состоящий из одного элемента, равного 0.

2. Для каждого элемента x из списка N:

Записать в конец списка F элементы, полученные из списка F, путем увеличения каждого его элемента на величину x, где x - значение текущего элемента из списка N.

3. Отсортировать элементы списка F в порядке возрастания.

4. Удалить из списка F все элементы, больше X.

5. Последний элемент из списка F является решением задачи.

 

Пример:

Красным - отмечены добавляемые на каждом шаге в конец списка числа

n - порядковый номер элемента из списка N, в расчетах не участвует.

N= {4.1, 3.2, 5.5, 7, 6.3};  R = 13.4;

1. F= {0}

2.1 n=1; х = 4.1; F= {0, 4.1}

2.2 n=2; х = 3.2; F= {0, 4.1, 3.2, 7.3}

2.3 n=3; х = 5.5; F= {0, 4.1, 3.2, 7.3, 5.5, 9.6, 8.7, 12.8}

2.4 n=4; х = 7,0; F= {0, 4.1, 3.2, 7.3, 5.5, 9.6, 8.7, 12.8, 7, 11.1, 10.2, 14.3, 12.5, 16.6, 15.7, 19.8}

2.5 n=5; х = 6.3; F= {0, 4.1, 3.2, 7.3, 5.5, 9.6, 8.7, 12.8, 7, 11.1, 10.2, 14.3, 12.5, 16.6, 15.7, 19.8, 6.3, 10.4, 9.5, 13.6, 11.8, 15.9, 15, 19.1, 13.3, 17.4, 16.5, 20.6, 18.8, 22.9, 22, 26.1}

3. F= {0, 3.2, 4.1, 5.5, 6.3, 7, 7.3, 8.7, 9.5, 9.6, 10.2, 10.4, 11.1, 11.8, 12.5, 12.8, 13.3, 13.6, 14.3, 15, 15.7, 15.9, 16.5, 16.6, 17.4, 18.8, 19.1, 19.8, 20.6, 22, 22.9, 26.1}

4. F= {0, 3.2, 4.1, 5.5, 6.3, 7, 7.3, 8.7, 9.5, 9.6, 10.2, 10.4, 11.1, 11.8, 12.5, 12.8, 13.3}

5.  13.3

 

Для того, чтобы  получить список слагаемых, из которых получилось результирующее число, можно для каждого элемента списка F хранить набор слагаемых. Тут возможны разные варианты, в своём примере  я использовал СписокЗначений.

Пример под публикацией был написан для УТ 10.3 в режиме совместимости 8.3.6 и выше (Обычное приложение)

Как работает обработка (см. рисунок формы): 

1. Заполняем "Дата", "Склад", "Сумма себестоимости"

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

3. По кнопке "Создать реализацию", соответственно создается реализация, которая заполняется из отмеченных на форме строк. 

Проверено на следующих конфигурациях и релизах:

  • Управление торговлей, редакция 10.3, релизы 10.3.46.3

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1959    stopa85    12    

34

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4882    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    7929    5    SpaceOfMyHead    17    

56

Мини-обзор разных решений задач

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    3189    RustIG    6    

25

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    8030    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4638    fishca    13    

37

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    9063    John_d    73    

46
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. starik-2005 3040 22.01.24 13:24 Сейчас в теме
Пока у нас слагаемых немного (допустим, до 20) - это не так и долго работает. Но длина массива уже 2^20 ~ 1 000 000. При длине массива в 30 слагаемых у нас уже миллиард с лишним элементов в массиве. А если у нас сотня слагаемых?
2. Johnson1987 28 23.01.24 06:19 Сейчас в теме
(1) Это правда. Но мне удалось получить достаточно точный результат, используя этот метод и творческий подход. Используя массив до 20 слагаемых
3. starik-2005 3040 23.01.24 10:30 Сейчас в теме
(2)
Используя
Ну, предположу, можно отсечь все, что больше или сумма чего больше, чем требуемая. Но это вряд ли поможет в настоящих ситуациях, когда сумма значительно больше любого слагаемого.
В принципе, здесь нет необходимости хранить суммы - можно просто хранить максимальный результат, но придется каждый раз суммировать элементы заново, хотя это и не должно увеличить количество итераций. Но 2^100 - это ну очень много. Как вариант решения можно рассмотреть алгоритм рюкзака, но он тоже займет какое-то количество памяти. При творческом подходе это количество можно сократить до искомой суммы, деленной на наименьший общий делитель слагаемых, ну или рассчитать до рублей, но длина массива на элемент будет равна количеству рублей. Ну там можно и еще покреативить и сделать динамический индекс и т.д. - народ, предположу, такие штуки мутит.
Оставьте свое сообщение