Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Поиск максимального пути в графе с циклами

444
11 мая 2010 года
patison
323 / / 15.03.2007
Имеется ориентированный граф, содержащий циклы, с пронумерованными путями.
Все пути, имеют вес = 1 (путь из одного узла в другой).
Необходимо найти узел, выйдя из которого можно пройти максимальное кол-во узлов, не посещая узлы более 1 раза.

Перебирал алгоритмы Форда-Беллмана (для поиска минимального пути), Флойда, Дейкстры... Но всё это, как мне кажется, не то. Применяя эти алгоритмы на графе с циклами, максимальный путь равен бесконечности, т.е. по сути нарушается правило "...не посещая узлы более 1 раза".

Как мне кажется, тут нужен какой-то гибрид Дейкстры и Гамильтона (гамильтоновых путей). Но что-то никак не пойму каким образом реализовать это дело.

Искал на алголисте - ничего толковово не нашёл.
Буду благодарен каким-нибудь наводкам.

Спасибо.

зы пример графа прикрепляю.
8.4K
11 мая 2010 года
z0rch
275 / / 02.09.2008
а если просто, поиском вглубину перебрать всевозможные пути, и выбрать среди них самый длинный?
upd: ну где то так:
Код:
int derevo[N][N]//граф
bool used[N]; //определяет наличие вершины в пройденном пути
int n; //количество элементов

void FindDepth_r(int versh)
{
    for(int i=0;i<n;i++)
        if(derevo[versh-1]==1 && !used) //раз все пути весом в единицу
        {
            used=true;
            FindDepth_r(i+1);
        }
    used[versh-1]=false;
}

перед первым вызовом функции сделаете used[вершина_из_которой_начинаете_поиск]=true;
возможно вам придется перебрать таким образом каждую вершину
444
11 мая 2010 года
patison
323 / / 15.03.2007
Идея ясна, но это не совсем то... Во-первых не хотелось-бы сюда рекурсию приплетать... Т.к. граф может содержать достаточно большое кол-во узлов.

Имеется в данный момент алгоритм Форда, для нахождения кратчайших путей. Работает вполне исправно.
Код всего класса приводить не буду, только основное.

Код:
// Инициализация
// adjMatrix это матрица смежности. состоит из 0 и 1.
// если adjMatrix[j] = 1, значит существует путь (со стоимостью 1) из i в j (не наоборот, граф направленный).

void Mathematics::Init(int nodes, int**adjMatrix)
{
    int i, j;
    this->n = nodes;
    for (i = 0; i < this->n; i++)
        for (j = 0; j < this->n; j++) {
            if ( adjMatrix[j] != 0) {
                this->edges[e].u = i;
                this->edges[e].v = j;
                this->edges[e].w = adjMatrix[j];

                ++e;
            }
    }
}
...

//А вот и сам алгоритм (часть метода с реализацией алгоритма):
        int i, j;

        for (i = 0; i < n; ++i)
                this->d = INFINITY; // INFINITY инициализируется как 99999

        this->d = 0; // s - индекс узла, из которого начать поиск

        for (i = 0; i < n - 1; ++i)
                for (j = 0; j < e; ++j)
                    if (d[edges[j].v] - d[edges[j].u] > edges[j].w )
                            d[edges[j].v] = d[edges[j].u] + edges[j].w;


Всё это дело, насколько я помню, можно как-то адаптировать для поиска Максимального пути. Пролистав конспект 2х летней давности, нашёл что достаточно INFINITY превратить в минус бесконечность (пусть это будет -99999), а в алгоритме поменять просто знак в сравнивании:
 
Код:
for (i = 0; i < n - 1; ++i)
                for (j = 0; j < e; ++j)
                    if (d[edges[j].v] - d[edges[j].u] < edges[j].w ) // вот Тут
                            d[edges[j].v] = d[edges[j].u] + edges[j].w;


И всё. Только вот не работает оно как надо. На маленьком графе (5 узлов), выдаёт мне длины путей - 9, 8, 10, и т.п.

Есть какие-то мысли как можно иначе адаптировать алгоритм Форда? Возможно я где-то накосячил.
444
11 мая 2010 года
patison
323 / / 15.03.2007
Похоже, проблема в циклах. Сгенерил небольшой граф без циклов - модифицированный Форд работает. Находит длинные пути.
Осталось понять, каким образом избавиться от циклов, и можно-ли это вообще делать (не пострадает-ли от этого моя модель...).
444
12 мая 2010 года
patison
323 / / 15.03.2007
Вобщем, решения с общеизвестными алгоритмами так и не нашёл. Пришлось прибегнуть к написанию рекурсивного алгоритма. Алгоритм находит 1 или все максимальные пути в графе с циклами, начиная из указанного узла. Суть алгоритма схожа с тем что предложил z0rch.

Кому интересно - чуть позже выложу сорц.
61K
12 мая 2010 года
ням
1 / / 12.05.2010
я так понял вы говорите про язык С++, а не могли бы вы мне помочь в С# сделать что-то подобное, нужно сделать поиск вглубину по этой програмке

ЗЫ. буду очен благодарен, так как не очень хорошо понимаю эту тему
61K
03 июня 2010 года
Butters
1 / / 03.06.2010
Доброго времени суток,

Заинтересовала ваша задача patison.

В сети не так много решений поиска длинного пути в графе.
Не могли бы вы выложить свою работу для ознакомления? :)

Спасибо
Аноним
?????????????
НАРОД я немного без дуплей, - как это поиск максимального пути в графе С ЦИКЛАМИ
максимальный путь по-моему ищется только в ориентированном графе БЕЗ ЦИКЛОВ.
а вы сейчас имхо ищете определитель прямоугольной матрицы =))
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог