Помогите решить задачу оптимизации
От: Айкон Россия  
Дата: 20.11.13 12:16
Оценка:
Образное описание:
1. Представьте себе трафарет.
2. Теперь, представте что у вас кучка самых разных трафаретов из N штук (N >= 1).
3. Вы складываете их в шляпу, подкидываете ввверх, они удараряются об потолок и падают на пол.
4. Трафаеты раскадало по полу, но многие из них лежат внахлёст один на другой.
5. Суммарная площадь пола накрытая трафаретами — S. Из-за лежащих внахлёст трафаретов S значительно меньше суммарной площади всех трафаретов.

Задача: найти такую минимальную (по количеству штук) комбинацию трафаретов, что они будут покрывать 80% от S.


Исходные данные этой же задачи, но вместо рисунков трафаретов — числа из диапазона [1-10000]:


            var maxValue = 10000;
            var rnd = new Random();
            int trafaretsNum = rnd.Next(1, 100); // количество трафаретов
            int[][] trafarets = new int[trafaretsNum][]; // первый уровень - непосредственно трафарет, второй уровень - точки трафарета
            for (int i = 0; i < trafarets.Length; i++)
            {
                int trafaretSize = rnd.Next(1, 1000); // размер (количество точек) трафарета
                trafarets[i] = new int[trafaretSize];
                for (int j = 0; j < trafarets[i].Length; j++)
                {
                    int min = rnd.Next(1, maxValue);
                    int max = rnd.Next(min, maxValue) + 1;
                    int val = rnd.Next(min, max);
                    trafarets[i][j] = val;
                }
                trafarets[i] = trafarets[i].OrderBy(a => a).ToArray(); // сортируем просто для красоты
            }
            Dictionary<int, object> dict = new Dictionary<int, object>();
            foreach (int[] trafaret in trafarets)
            {
                foreach (int val in trafaret)
                {
                    if (!dict.ContainsKey(val))
                    {
                        dict.Add(val, null);
                    }
                }
            }
            int[] S = dict.Keys.OrderBy(a => a).ToArray();  // накрытый трафаретами набор чисел. Отсортированы просто для красоты.


Необходимо найти такой минимальный набор трафаретов (trafarets[i]), что бы накрыть 80% чисел из массива S.

Задача, на самом деле сугубо практическая и бизнесовая, просто я её максимально выхолостил для простоты понимания.
По возможности нужно максимально производительное решение, т.к. выбор оптимального набора "трафаретов" выполняется на потоке тысячи раз.
Re: Помогите решить задачу оптимизации
От: watchmaker  
Дата: 20.11.13 13:29
Оценка:
Здравствуйте, Айкон, Вы писали:


А>Задача: найти такую минимальную (по количеству штук) комбинацию трафаретов, что они будут покрывать 80% от S.

Эта задача в литературе зовётся как partial set cover.


А>По возможности нужно максимально производительное решение, т.к. выбор оптимального набора "трафаретов" выполняется на потоке тысячи раз.

Одновременно точно и быстро её не решить — NP-hard всё-таки.
Приближённые алгоритмы для partial set cover есть. Но с ними всё тоже достаточно печально. Более-менее хорошие приближения можно получать только для множеств специального вида (но и там типична ситуация, когда выдающимся считается алгоритм, который ошибается не более чем в десяток раз :)
Re[2]: Помогите решить задачу оптимизации
От: Айкон Россия  
Дата: 20.11.13 13:49
Оценка:
Печально

А вы не могли бы привести решение для моей трактовки задачи, потому как количество высшей математики в документах по запросу partial set cover очень пугает
Re[3]: Помогите решить задачу оптимизации
От: Аноним  
Дата: 20.11.13 14:35
Оценка: :))
Здравствуйте, Айкон, Вы писали:

А>Печально


А>А вы не могли бы привести решение для моей трактовки задачи, потому как количество высшей математики в документах по запросу partial set cover очень пугает


Там несложная математика. Почитайте поверхностно про теорию множеств, логарифмы, числовые последовательности и схождение, мат. функции с множеством переменных, функцию max и min, комбинации в комбинаторике, условную вероятность, математическое ожидание, дисперсию, сигма-нотацию (http://www.mathsisfun.com/algebra/sigma-notation.html), вроде, еще графы, и потом еще раз статью.
Re[3]: Помогите решить задачу оптимизации
От: watchmaker  
Дата: 20.11.13 14:54
Оценка: 2 (1)
Здравствуйте, Айкон, Вы писали:

А>привести решение для моей трактовки задачи

:)
Ну разве что классический жадный алгоритм могу привести. Но в нём-то как раз всё просто — на каждой итерации нужно брать трафарет с самым большим числом ещё не покрытых значений и добавлять его в решение. И останавливаться как только накопили нужное число покрытых точек.

А>потому как количество высшей математики в документах по запросу partial set cover очень пугает

Так надо сначала выяснить, хорошо подходит твоя задача под условия алгоритма. Вот в этой конкретной статье используются либо ограничения на максимальный размер множества, либо на максимальную частоту вхождения элемента. Ну то есть целесообразность применения зависит грубо-говоря от соотношений между maxValue, trafaretsNum и trafaretSize. В любом случае, стоит сначала начать с жадного, и посмотреть на примеры, где качество его решений не устраивает, — а потом с ними и бороться.
Re: Помогите решить задачу оптимизации
От: wildwind Россия  
Дата: 21.11.13 06:06
Оценка: +1
Здравствуйте, Айкон, Вы писали:

А>Задача, на самом деле сугубо практическая и бизнесовая, просто я её максимально выхолостил для простоты понимания.


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