Нахождение X деревьев с наименьшей стоимостью в графе

У меня есть график с N узлами и ребрами со стоимостью. (граф может быть полным, но также может содержать нулевые ребра).

Я хочу найти K деревьев в графе (K ‹ N), чтобы убедиться, что каждый узел посещен, а стоимость будет минимально возможной.

Любые рекомендации, какой лучший подход может быть?

Я попытался изменить задачу, чтобы найти только одно минимальное остовное дерево, но безуспешно. Спасибо за любую подсказку!

ИЗМЕНИТЬ

маленькая деталь, которая может быть существенной. Чтобы стоимость не связана с пересечением края. Стоимость - это цена ПОСТРОЕНИЯ такого преимущества. Как только ребро построено, вы можете перемещаться по нему вперед и назад без каких-либо затрат. Проблема не в том, чтобы "проехать по всем узлам", проблема в том, чтобы "создать сеть среди всех узлов". прошу прощения за предыдущее объяснение

История Вот история, которую я услышал и пытаюсь решить.

Есть город, без подключения к электричеству. Электрическая компания может подключить к электричеству только K домов. Другие дома можно соединить, пропустив кабели от уже подключенных домов. Но падение этого кабеля чего-то стоило. Цель состоит в том, чтобы выбрать, какие K домов будут подключены напрямую к электростанции, а какие дома будут подключены отдельными кабелями, чтобы обеспечить минимальную стоимость кабеля и охват всех домов :)


person relaxxx    schedule 26.09.2011    source источник
comment
Я думаю, что это следует называть минимальным остовным деревом с наименьшей стоимостью. Я ответил на него как на классическую задачу о пути с наименьшей стоимостью (и получил отрицательный голос, когда перечитывал задачу!) Моя вина, что я ответил слишком быстро.   -  person Codie CodeMonkey    schedule 26.09.2011
comment
Как проблема графа, которую вы описываете, моделирует вашу бизнес-задачу? Во-первых, где применяется ограничение на пути? Обычно инженерные соединения моделируются деревьями.   -  person David Nehme    schedule 26.09.2011
comment
@ Дэвид, ты прав на 100, мой плохой ... Я снова редактирую вопрос   -  person relaxxx    schedule 26.09.2011
comment
+1: Отредактированная проблема - очень интересный вопрос [ну, наконец, по-моему]. Можете ли вы предоставить, откуда это? приложение из реальной жизни? конкурс?   -  person amit    schedule 27.09.2011


Ответы (7)


Как уже упоминалось, это сложно NP. Однако, если вы готовы принять хорошее решение, вы можете использовать имитацию отжига. Например, задача коммивояжера является NP-трудной, но почти оптимальные решения могут быть найдены с помощью имитации отжига, т.е. http://www.codeproject.com/Articles/26758/Simulated-Annealing-Solving-the-Travelling-Salesma

person Codie CodeMonkey    schedule 26.09.2011
comment
@relaxxx: Я так и думал, но попробовать стоило. Надеюсь, ваши графики маленькие! - person Codie CodeMonkey; 26.09.2011

Вы описываете что-то вроде покрытия пути с ограничениями по мощности. Она относится к семейству задач коммивояжера/маршрутизации транспортных средств и является NP-сложной. Чтобы создать алгоритм, вы должны спросить

  1. Вы собираетесь запускать его только на небольших графах.
  2. Собираетесь ли вы запускать его только на особых случаях графов, которые имеют точные алгоритмы.
  3. Можете ли вы жить с эвристикой, которая приблизительно решает проблему.
person David Nehme    schedule 26.09.2011

Предположим, вы можете найти минимальное остовное дерево в O(V^2), используя алгоритм Прима.

Для каждой вершины найдите минимальное остовное дерево с этой вершиной в качестве корня.

Это будет O(V^3), так как вы запускаете алгоритм V раз.

Отсортируйте их по общей массе (сумма весов их вершин) графа. Это O(V^2 lg V), который потребляется O(V^3), так что по сути бесплатно с точки зрения сложности заказа.

Возьмите X наименее массивных графов — их корни — это ваши «якоря», которые напрямую связаны с сеткой, поскольку они, скорее всего, будут иметь самые короткие пути. Чтобы определить, какой маршрут он выберет, вы просто следуете пути к корню в каждом узле в каждом дереве и подключаете самый короткий путь. (Это может быть дополнительно оптимизировано путем сортировки всех путей к корню и использования сначала только самых коротких. Это позволит оптимизировать следующие итерации. Поиск пути к корню — O(V). Поиск его для всех времен VX — O(V^2 * X). делая это для каждого V, вы смотрите на O(V^3 * X) Это больше, чем ваша самая большая сложность, но я думаю, что средний случай для них будет небольшим, даже если их худший случай большой).

Я не могу доказать, что это оптимальное решение. На самом деле, я уверен, что это не так. Но когда вы рассматриваете электрическую сеть из 100 000 домов, вы не можете рассматривать (с каким-либо практическим применением) жесткое решение NP. Это дает вам очень хорошее решение в O (V ^ 3 * X), ​​которое, я думаю, даст вам решение, очень близкое к оптимальному.

person corsiKa    schedule 26.09.2011
comment
Я не совсем понимаю твое решение. Конечным результатом должно быть X связанных n-кортежей ребер. Каждый кортеж может принадлежать разным остовным деревьям. Как я могу получить это решение из вашего предложения? - person relaxxx; 26.09.2011
comment
Минимальное остовное дерево можно вычислить в O(V^2) с помощью алгоритма Прима. Каждое остовное дерево будет иметь наименьшее расстояние до каждого узла, предполагая, что это корень. Позволив каждому узлу на мгновение стать корнем и вычислив полученное минимальное остовное дерево, вы можете найти то, что имеет наиболее оптимальный набор всех путей. Не могли бы вы описать (просто говоря), какую еще цель вы пытаетесь достичь? Ваше редактирование, кажется, указывает на то, что вы удаляете стоимость - я просто не понимаю, как это возможно или что оно пытается представить. - person corsiKa; 26.09.2011
comment
Пожалуйста, посмотрите историю в моем вопросе :) - person relaxxx; 26.09.2011
comment
Я переформулировал свой ответ с неоптимальным, но более практичным решением. - person corsiKa; 26.09.2011
comment
благодарю вас за ваше усилие! ваше решение красивое и практичное, к сожалению, как вы сказали, оно не даст оптимальных результатов... Если вам интересно, пожалуйста, посмотрите мой ответ - person relaxxx; 26.09.2011
comment
Ну, честно говоря, ваше решение выглядит почти идентично моему, за исключением того, что по какой-то причине вы пытаетесь использовать случайные привязки, пока не получите правильное место, где я выбираю корни самых маленьких MST. Это увеличивает ваш заказ до O(V^4), в то время как мой O(V^3 lg V). Кроме того, они идентичны, и у них обоих есть проблема, что они не являются оптимальными. - person corsiKa; 27.09.2011
comment
О, извините, я, вероятно, неправильно понял ваше решение... Я собираюсь прочитать его снова :) - person relaxxx; 27.09.2011
comment
Я до сих пор не вещи почти идентичны. Я думаю, что моя может быть оптимальной (правда, не доказывал) ... Я думаю, что просто плохо описываю, поэтому взгляните на картины - person relaxxx; 27.09.2011

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

Глядя на доказательство правильности алгоритма Прима на http://en.wikipedia.org/wiki/Prim%27s_algorithm, рассмотрите возможность использования минимального связующего дерева и удаления самых дорогих ссылок X-1. Я думаю, приведенное здесь доказательство показывает, что результат имеет ту же цену, что и наилучший возможный ответ на вашу проблему: единственная разница в том, что при сравнении ребер вы можете обнаружить, что новое ребро соединяет два отдельных компонента, но в этом случае вы можете сохранить количество разделенных компонентов, удалив ребро со стоимостью, не превышающей стоимость нового ребра.

Поэтому я думаю, что ответ на вашу проблему состоит в том, чтобы взять минимальное остовное дерево и удалить самые дорогие ссылки X-1. Это, безусловно, так для X=1!

person mcdowella    schedule 26.09.2011
comment
вы правы, путь может быть деревом... Я отредактировал вопрос... ваше решение хорошее, но только для случая X=1 - person relaxxx; 26.09.2011

Вот попытка решить эту...

Для X = 1 я могу рассчитать минимальное остовное дерево (MST) с помощью алгоритма Прима для каждого узла (этот узел единственный, подключенный к сетке) и выбрать тот, у которого самая низкая общая стоимость.

Для X=2 я создаю дополнительный узел (узел электростанции) рядом с моим графиком. Я соединяю его со случайным узлом (например, N0) ребром со стоимостью 0. Теперь я уверен, что у меня есть одна правильная вилка электростанции (случайный узел определенно будет в одном из деревьев, поэтому все дерево будет подключено). Теперь итерационная часть. Я беру другой узел (например, N1) и снова подключаюсь к PP с нулевым преимуществом стоимости. Сейчас я вычисляю MST. Затем повторите этот процесс с заменой N1 на N2, N3... Итак, я буду тестировать каждую пару [N0, NX]. Побеждает самая низкая стоимость MST.

Для X>2 это действительно то же самое, что и для X=2, но я должен проверить подключение к PP для каждого (x-1)-кортежа и вычислить MST

с x^2 для MST у меня есть сложность около (N over X-1) * x^2... Довольно сложно, но я думаю, что это даст мне ОПТИМАЛЬНОЕ решение

что ты думаешь?

редактировать случайным узлом Я имею в виду случайный, но ИСПРАВЛЕННЫЙ узел

попытка визуализации для x=2 (каждое описание принадлежит изображению над ним)

введите здесь описание изображения

Пусть это будет наш город, узлы A-F — дома, ребра — кандидаты на будущие кабели (каждый требует затрат на строительство)

введите здесь описание изображения

Просто для изображения, это может быть решением

введите здесь описание изображения

Пусть зеленый будет электростанцией, вот так может выглядеть подключение к одному дереву

введите здесь описание изображения

Но это другое подключение на самом деле то же самое (подключение к электростанции (ПП) стоит столько же, кабели остаются нетронутыми). Поэтому мы можем установить один из узлов в качестве фиксированной точки контакта с pp. Мы можем быть уверены, что узел будет в одном из деревьев, и неважно, в каком месте дерева он находится.

введите здесь описание изображения

Итак, пусть это будет наша фиксированная ситуация с G как PP. Добавлено ребро (B,G) с нулевой стоимостью.

введите здесь описание изображения

Теперь я пытаюсь подключить второе соединение с PP (A, G, стоимость 0)

введите здесь описание изображения

Сейчас рассчитываю МСТ из ПП. Поскольку красные ребра являются самыми дешевыми (на самом деле они могут иметь даже отрицательную стоимость), можно быть уверенным, что они оба будут в MST.

введите здесь описание изображения

Итак, при запуске MST я получаю что-то вроде этого. Представьте, что вы отсоединили PP и осталось два дерева с МИНИМАЛЬНОЙ СТОИМОСТЬЮ. Это лучшее решение, поскольку А и Б являются соединениями с РР. Сохраняю стоимость и иду дальше.

введите здесь описание изображения

Теперь я делаю то же самое для соединений B и C.

введите здесь описание изображения

Я мог бы получить что-то подобное, поэтому сравните стоимость с предыдущим и выберите лучший.

Таким образом, я должен попробовать все пары соединений (B,A) (B,C) (B,D) (B,E) (B,F), и победит самый дешевый.

Для X = 3 я бы просто проверил другие кортежи с одним фиксированным снова. (А,В,С) (А,В,D) ... (А,С,D) ... (А,Е,F)

person relaxxx    schedule 26.09.2011
comment
Я не думаю, что это сработает [оптимизировать], так как вы принудительно подключаете 2 узла к «электростанции», что, возможно, стоит подключить два других узла. - person amit; 27.09.2011
comment
@amit они соединены ребром с нулевой стоимостью, поэтому алгоритм мини-MST обязательно использует их оба в MST. - person relaxxx; 27.09.2011
comment
если электростанцию ​​можно подключить к каждому узлу со стоимостью 0, это меняет всю картину. Так ли это? Кроме того, когда вы создаете все эти MST, вам нужно «знать», какие вершины «не учитывать» в каждом MST. Я могу упустить смысл вашего алгоритма, можете ли вы сделать его более формальным и объяснить, как доказать, что он оптимизирован? - person amit; 27.09.2011
comment
электростанцию ​​можно подключить ровно к X узлам. X задается на входе. Я попытаюсь визуализировать подключение электростанции на простой схеме. - person relaxxx; 27.09.2011
comment
Псевдодиаграмма @amit готова :) - person relaxxx; 27.09.2011

Я просто придумал простое решение следующим образом:

N - количество узлов

C - прямое подключение к сети

E - доступные ребра


1. Отсортировать все ребра по стоимости

2, повторите (N-C) раз:

  1. Возьмите самое дешевое доступное преимущество
  2. Проверьте, не вызовет ли добавление этого края круги в уже добавленном крае.
  3. Если нет, добавьте это ребро

3. Вот и все... Вы получите C непересекающихся наборов ребер, соедините каждый набор с сеткой

person relaxxx    schedule 01.10.2011

Звучит как знаменитая задача коммивояжера. Известно, что задача является NP-трудной. Взгляните на Википедию в качестве отправной точки: http://en.wikipedia.org/wiki/Travelling_salesman_problem< /а>

person omt66    schedule 26.09.2011