Что такое жадный алгоритм для этой задачи, который минимально оптимален доказательство?

#algorithm #greedy

#алгоритм #жадный

Вопрос:

Детали немного пугают, справедливое предупреждение, лол:

Я хочу настроить счетчики на этаже моего здания, чтобы поймать кого-то; предположим, что мой этаж — это числовая строка от 0 до длины L. Конкретный тип измерителя, который я разрабатываю, имеет радиус обнаружения, который составляет 4,7 метра в направлении -x и x (диаметр обнаружения 9,4 метра). Я хочу настроить их таким образом, чтобы, если человек, которого я пытаюсь найти, ступит в любую точку пола, я буду знать. Однако я не могу просто установить счетчик в любом месте (это может раздражать других жителей); поэтому есть только n допустимых местоположений, в которых я могу установить счетчик. Кроме того, эти счетчики дороги и требуют много времени, поэтому я хотел бы использовать как можно меньше.

Для простоты вы можете предположить, что счетчик имеет ширину 0, и что каждое допустимое местоположение — это просто точка на упомянутой числовой строке. Что такое жадный алгоритм, который размещает как можно меньше метров, будучи в состоянии обнаружить весь коридор длиной L, как я хочу, или, если обнаружение всего коридора невозможно, выведет false для набора из n местоположений, которые у меня есть (и, если он не способенчтобы обнаружить весь коридор, все еще использует как можно меньше метров при попытке сделать это)?

Редактировать: некоторые разъяснения о возможности обнаружения всего коридора или нет

Комментарии:

1. Можете ли вы привести пример для вашей проблемы? Мне довольно сложно это понять.

2. Вы просто хотите найти самое длинное покрытие интервала? Где пересечение будет учитываться только один раз?

3. @lierwu Представьте, что у вас есть список из n допустимых мест для установки счетчика (n_1, n_2, n_3, n_4). Я знаю, что n_1 находится в 6 футах от конца коридора, n_2 — в 20 футах от конца коридора, n_3 — 18 футов, n_4 — 2 фута. Скажем, что если я помещу счетчик в n_2; положение его самого левого края диапазона обнаружения (отрицательное направление x) равно s = 20 — 4,7 = 15,3 фута от конца коридора. Самый правый край равен f = 20 4,7 = 24,7 фута от конца коридора. Сделайте это для других позиций, и вы получите позиции экстремумов диапазона обнаружения каждого метра вдоль упомянутой числовой строки.

4. @lierwu Я не хочу никаких пересечений между обнаружением каждого счетчика, когда я размещаю их в коридоре; Я не хочу использовать больше метров, чем необходимо; Я хочу иметь возможность обнаруживать весь коридор, если это возможно (учитывая n возможных местоположений), или, если это невозможно, для алгоритмачтобы вернуть false, я могу попробовать другую комбинацию допустимых местоположений.

5. @lierwu Итак, я думаю, я хотел бы вернуть наименьший набор допустимых местоположений, при этом обнаруживая весь коридор, поэтому я попросил минимально оптимальное решение (в отличие от самого большого набора, который вы обычно видите с другими жадными алгоритмами)

Ответ №1:

Учитывая:

  • L (длина коридора)
  • список из N допустимых позиций для размещения метра ( p_0 p_N-1 ) радиуса 4.7

Вы можете определить в O (N) либо действительное и минимальное («хорошее») покрытие всего коридора, либо доказательство того, что такого покрытия не существует, учитывая следующие ограничения (псевдокод):

 // total = total length; 
// start = current starting position, initially 0
// possible = list of possible meter positions
// placed = list of (optimal) meter placements, initially empty
boolean solve(float total, float start, List<Float> possible, List<Float> placed):

   if (total-start <= 0): 
        return true; // problem solved with no additional meters - woo!
   else:
        Float next = extractFurthestWithinRange(start, possible, 4.7);
        if (next == null):
             return false; // no way to cover end of hall: report failure
        else:
             placed.add(next); // placement decided
             return solve(total, next   4.7, possible, placed); 
  

Где extractFurthestWithinRange(float start, List<Float> candidates, float range) возвращает null , если внутри нет candidates range start , или возвращает последнюю позицию p в candidates таком, что p <= start range — а также удаляет p , и все кандидаты c такие, что p >= c .

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

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

 // remaining = length (starts at hallway length)
// possible = positions to place meters at, starting by closest to end of hallway
// placed = positions where meters have been placed
boolean solve(float remaining, List<Float> possible, Queue<Float> placed):

   if (remaining <= 0): 
        return true; // problem solved with no additional meters - woo!
   else:
        // extracts points p up to and including p such that p >= remaining - range
        Float next = extractFurthestWithinRange2(remaining, possible, 4.7);
        if (next == null):
             return false; // no way to cover start of hall: report failure
        else:
             placed.add(next); // placement decided
             return solve(next - 4.7, possible, placed); 
  

Комментарии:

1. «… оптимальное покрытие (= никакое возможное допустимое покрытие не могло бы использовать меньше метров — потому что наши пробелы уже максимально широки)» Как он может быть максимально широким, если нам разрешено выбирать элемент p, который равен> = оставшемуся диапазону, как указано во втором кодовом блоке? Разве мы не всегда выбираем элемент из возможных, который ближе всего к ранее размещенному элементу?

2. Вы не выбираете просто любой элемент, который есть >= remaining - range — вы выбираете самый дальний , который удовлетворяет этому условию. То есть тот, который оставляет наибольший разрыв (но он все еще находится в пределах диапазона от предыдущего метра, потому что в противном случае мы бы не покрыли весь зал)

Ответ №2:

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

И вы делаете это путем индукции по размеру лексикографически последнего оптимального решения. Случай пола нулевой длины и отсутствия монитора тривиален. В противном случае вы демонстрируете, что нашли первый элемент лексикографически последнего решения. И покрытие остальной части строки оставшимися элементами — это ваш шаг индукции.

Техническое примечание, чтобы это сработало, вам должно быть разрешено размещать станции мониторинга за пределами линии.

Комментарии:

1. Я больше ищу алгоритм, который передает это