Приветствую, уважаемый аноним. Перейду сразу к делу. Дан массив пар числел, например ((0.08, -0.12), (0.07, -0.13), (0.03, -0.7), (0.14, -0.2)). Надо из каждой пары выбрать одно число так, чтобы сумма всех выбранных чисел была минимальной не отрицательной.
Число перестановок в задаче ОПа равно 2^n, где n -- число пар чисел. Очевидно, что если ебашить перебором на любом мало-мальски длинном листе, то он никогда не решит эту задачу за отведенное время. ОП, какой длины типичный лист с парами чисел?
Посоны, давайте поменяем условие задачи ОПа на более веселое. Теперь нужно приближенно решить его задачу наиболее быстрым способом.
Тестировать будем на данных для которых я уже нашел решение брутфорсом.
Будем использовать такую метрику: вы постите решение (индексы или уже выбранный список) + время работы вашего алгоритма в мс. Далее умножаем отклонение в позициях от правильного на мс работы. Победит тот у кого это число наименьшее.
Могу предложить такой алгоритм: сначала выбираешь из пар такие числа чтобы модуль суммы был наименьшим - так ты не убежишь от нуля далеко. Потом можно пройтись по массиву еще несколько раз, меняя изначальный выбор в том случае если удается получить неотрицательную сумму меньшую чем в предыдущем случае. Это должно быть быстрее полного перебора.
>>1044842 > Потом можно пройтись по массиву еще несколько раз, меняя изначальный выбор в том случае если удается получить неотрицательную сумму меньшую чем в предыдущем случае Но тогда нужно помнить индексы выбора, чтобы менять числа пары.
>>1045613 >Ответ неверный А верного ответа никто и не просил, просили лучшее соотношение произведения точности на время. >даже в приближении должен дать больше 2.65 Там и так сумма наибольших чисел из каждой пары, куда еще больше? Очевидная шутка юмора была.
>>1044642 (OP) Берешь сумму всех максимальных, и сохраняешь модуль разности всех пар. На этих разностях и сумме получаешь 0-1 рюкзак, решаешь его, и где получаешь 1 - меняешь элемент из пары на минимальный.
Оп здесь. Анализ тестовой выборки выявил некоторые особенности в данных, поэтому получилось решить жадно с приемлемой точностью. Всем спасибо за участие.
Пхп макак врывается в тред. Решил вашу задачу полным перебором. https://ideone.com/2j90ze Поясняю как делал.
Так как массив состоит из пар, то каждую пару можно представить как бит. И выбирать из пары либо 1 либо 0 И вот всё что осталось это перебрать все двоичные числа в случае с 4 элементами от 0000 до 1111 беря вместо 0 и единицы соответственно нулевой и первый элемент каждой пары.
Далее все эти варианты сваливаются в кучу которая сортируется и из неё уже выбирается что нужно.
х1000, /1000 и 0.00001 в коде это потому что пхп не умеет сравнивать флоат числа :(
Для пхп суммы данных массивов: ["0.08 -0.13 0.03 0.14 "]=> float(0.12) ["-0.12 0.07 0.03 0.14 "]=> float(0.12) пусть оба и равны по 0.12, но между собой нихуя не равны, поэтому пришлось сначала домножать на много, брать целую часть, а потом снова делить в конце.
HALP