Minimum Set Cover - это вопрос, где вы должны найти минимальное количество наборов, необходимых для покрытия каждого элемента.
Например, представьте, что у нас есть набор X=array(1,2,3,4,5,6)
и 5 другой набор S, где
S[1]=array(1, 4)
S[2] =array(2, 5)
S[3] =array(3, 6)
S[4] =array(1, 2, 3)
S[5] =array(4, 5, 6)
Задача состоит в том, чтобы найти минимальное число множеств из S
, которые охватывают каждый элемент из X.
. Очевидно, что минимальное обложка в нашем случае будет S [4] и S [5], поскольку они охватывают все элементы.
Кто-нибудь есть идея, как реализовать этот код в PHP. Обратите внимание, что это NP-complete, поэтому нет быстрого алгоритма для его решения. Любое решение в PHP будет приветствоваться. И BTW это не домашнее задание, мне нужно использовать этот алгоритм в своем веб-приложении, чтобы создать список предложений.
Спасибо заранее.
Обновление 1
Существует множество приложений проблемы с установкой покрытия. Некоторые из интересных:
- Построение оптимальных логических схем
- Планирование экипажа воздушных судов
- Балансировка линии сборки
- Информационный поиск
- Проблема с художественной галереей.
- Последовательность генома
- Проблема с Red-Blue SetCover
Обновление 2
Например, здесь вы можете увидеть рабочую версию проблемы, о которой я упоминал. Здесь даже он визуально показывает множества. Но для этого мне нужен чистый PHP-код, если у кого-то есть его, пожалуйста, будьте любезны предоставить нам рабочий пример в PHP. Спасибо,
Обновление 3
Наконец, я решил проблему в PHP. Мое решение основано на алгоритме, предложенном в очень известной книге под названием Введение в алгоритмы, раздел охватывая. Вот как выглядит мое решение:
$MainSet=array(1, 2, 3, 4, 5, 6, 7);
$SubSet=array(array(1,4), array(2, 5), array(3, 6), array(1, 2, 3), array(4, 5, 6));
$UncoveredElements=$MainSet;
$CoveringSets=array();
while (count($UncoveredElements)>0){
$S=SubSetS($UncoveredElements, $SubSet);
if (is_array($S)){
$UncoveredElements=array_diff($UncoveredElements, $S);
$CoveringSets[]=$S;
}else
break; //finish work
}
echo "Sets that cover MainSet are:";
var_dump($CoveringSets);
//Subset S is chosen that covers as many uncovered elements as possible
function SubSetS($UncoveredElements, $SubSetArr){
$max=0; $s=array();
foreach($SubSetArr as $SubSet){
$intersectArr=array_intersect($UncoveredElements, $SubSet);
$weight=count($intersectArr);
if ($weight>$max){
$max=$weight;
$s=$SubSet;
}
}
if ($max>0)
return $s;
else
return 0;
}
Любые комментарии и идеи о моем решении? Для меня это решает мою проблему, вот чего я хотел. Но если вы предложите любую оптимизацию, исправление кода, пожалуйста, заполните бесплатно.
Кстати, большое спасибо участникам вопроса за их ценные ответы.
Окончательное обновление
Этот подход "Жадный" для проблемы с комплектом покрытия не всегда гарантирует оптимальное решение. Рассмотрим следующий пример:
С учетом: Элементы основного набора = {1, 2, 3, 4, 5, 6}
Теперь рассмотрим 4 подмножества следующим образом: Подмножество 1 = {1, 2}, Подмножество 2 = {3, 4}, Подмножество 3 = {5, 6}, Подмножество 4 = {1, 3, 5}.
Алгоритм Greedy для вышеупомянутого набора подмножеств дает минимальную обложку как:
Минимальная установленная обложка содержит подмножества = {1, 2, 3, 4}.
Таким образом, хотя минимальный набор подмножеств, охватывающих все элементы Main, представляет собой первые три подмножества, мы получаем решение, содержащее все 4 подмножества.