Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.02.2015, 01:06   #41
Вероника99
Форумчанин
 
Регистрация: 15.12.2013
Сообщений: 414
По умолчанию

Poma][a,кстати в вашем варианте с векторами, у меня тоже функция поиска пути не выдает никакого результата
Вероника99 вне форума Ответить с цитированием
Старый 01.02.2015, 01:34   #42
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 474
По умолчанию

Вероника99,
В общем поставил я себе на комп gcc. С нуля набрал прогу (портировал свой паскаль-исходник). Работает.
Причины:
1. Если в описании алгоритма написано о INFINITY - надо использовать.
2. Я плохо знаком с С и неправильно реализовывал цикл while.

Недостатки в моём исходнике
1. Я не умею работать с указателями в С и поэтому не могу разделить функции FU и печать пути - надо передавать массивы по ссылке и вызывать печать из main.
2. Всегда нужно разделять расчёты и вывод на экран. Из-за п.1 у меня не получилось.
3. Я не знаю как определить число MAXINT, поэтому применил INFINITY=10000.
Код:
#include <iostream>

using namespace std;

#define INFINITY 10000

//алгоритм Флойда-Уоршелла
int FU(int mV[][5], int D[][5], int C[][5], int V,int a,int b)
{
    /*
    матрицу веса дуги mV преобразуем в требуемый для алгоритма вид D
    - если i=j, то D[i, j]:=0
    - если из i в j нет ребра, то D[i, j]:=INFINITY (бесконечности)
    - иначе D[i, j] равно весу ребра из i в j
    подготовим матрицу для восстановления пути C
    */
    D=mV;
    for(int i=0; i<V; i++)
    {
        for(int j=0; j<V; j++)
        {
            if (D[i][j]==0)
                D[i][j]=INFINITY;
            if(i==j)
                D[i][j]=0;
            C[i][j]=i;
        }
    }
    /*
    Непосредственно сам цикл алгоритма Флойда-Уоршелла
    */
    for(int k=0; k<V; k++)
    {
        for(int i=0; i<V; i++)
        {
            for(int j=0; j<V; j++)
            {
                if( (D[i][k]!=INFINITY) && (D[k][j]!=INFINITY) )
                {
                    if(D[i][j]>D[i][k]+D[k][j])
                    {
                        D[i][j]=D[i][k]+D[k][j];
                        C[i][j]=C[k][j];
                    }
                }
            }
        }
    }

    cout << " D[][]:"<<endl;
    for(int i=0; i<V; i++)
    {
        for(int j=0; j<V; j++)
        {
            if(D[i][j]!=INFINITY)
                cout << " " << D[i][j];
            else
                cout << " inf";
        }
        cout <<endl;
    }

    cout << " C[][]:"<<endl;
    for(int i=0; i<V; i++)
    {
        for(int j=0; j<V; j++)
        {
            cout << " " << C[i][j];
        }
        cout <<endl;
    }

    // вывод пути между a и b
    if(a==b)
    {
        cout << "A==B" << endl;
        return 0;
    }
    if(D[a][b]==INFINITY)
    {
        cout << "No path" << endl;
        return 0;
    }
    // запись пути в стек
    int stk[1000];
    int len;
    int k;
    k=b;
    stk[0]=k;
    len=1;
    do
    {
        k=C[a][k];
        stk[len++]=k;
    }
    while(k!=a);
    // извлечение из стека и печать пути
    cout << "Path: <";
    for (int i=len; i>0; i--)
    {
        cout << " " << stk[i-1];
    }
    cout << ">" << endl;
}

int main()
{
    int GR[5][5]=
    {
        {0,3,2,0,0},
        {0,0,0,4,0},
        {0,0,0,6,0},
        {0,0,0,0,2},
        {0,0,0,0,0}
    };
    int D[5][5], C[5][5];
    FU(GR, D, C, 5, 3, 1);
    int GR2[5][5]=
    {
        {0,0,5,0,0},
        {7,0,0,0,10},
        {0,7,0,0,0},
        {0,0,6,0,4},
        {0,0,1,0,0}
    };
    FU(GR2, D, C, 5, 3, 1);
    return 0;
}
Результат работы проги
Код:
 D[][]:
 0 3 2 7 9
 inf 0 inf 4 6
 inf inf 0 6 8
 inf inf inf 0 2
 inf inf inf inf 0
 C[][]:
 0 0 0 1 3
 1 1 1 1 3
 2 2 2 2 3
 3 3 3 3 3
 4 4 4 4 4
No path
 D[][]:
 0 12 5 inf 22
 7 0 11 inf 10
 14 7 0 inf 17
 19 12 5 0 4
 15 8 1 inf 0
 C[][]:
 0 2 0 0 1
 1 1 4 1 1
 1 2 2 2 1
 1 2 4 3 3
 1 2 4 4 4
Path: < 3 4 2 1>
Посмотри и сравни со своей реализацией.
FPaul вне форума Ответить с цитированием
Старый 01.02.2015, 02:09   #43
Вероника99
Форумчанин
 
Регистрация: 15.12.2013
Сообщений: 414
По умолчанию

FPaul,спасибо огромное. Программа работает,но единственное что, все там же проблема,не показывает предыдущие вершины в путях,в матрице выводится только предпоследняя вершина...
Вероника99 вне форума Ответить с цитированием
Старый 01.02.2015, 02:25   #44
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 474
По умолчанию

Я не пойму о чём речь. Приведи пример таких данных вместе с эталонным ответом.
FPaul вне форума Ответить с цитированием
Старый 01.02.2015, 09:58   #45
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Утро доброе, граждане полуночники
Цитата:
Poma][a, а что ты изменил?
Отформатировал, не? Значит студия наврала..
Цитата:
Там все матрицы что-то делают.
Эт понятно
Цитата:
Если это не хранить, то для каждой новой пары вершин опять надо всё пересчитывать O(n^3).
Не-не-не
У нас же есть матрица смежности и матрица путей
За квадрат точно смогем восстановить
Poma][a вне форума Ответить с цитированием
Старый 01.02.2015, 10:49   #46
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 474
По умолчанию

Утро доброе!!!
А я, кажется, стелепатировал , что у ТС не получается!!!
Цитата:
Сообщение от Вероника99 Посмотреть сообщение
Если я ввожу например 1 5, программа глючит. Если две соединяющиеся вершины,выводит два раза вторую вершину.
Ха, а матрица с индексами от 0 до 4, и вершины нумеруются от 0 до 4. Вставь в начале вывода путей проверку на корректные диапазоны a и b.
FPaul вне форума Ответить с цитированием
Старый 01.02.2015, 15:35   #47
Вероника99
Форумчанин
 
Регистрация: 15.12.2013
Сообщений: 414
По умолчанию

FPaul, а нет,все работает,да,это я затупила,надо при вводе а ,b делать проверку, я у себя матрицу нарисовала начиная с 1 и до 5. Спасибо огромное!!
Вероника99 вне форума Ответить с цитированием
Старый 03.02.2015, 18:42   #48
Вероника99
Форумчанин
 
Регистрация: 15.12.2013
Сообщений: 414
По умолчанию

А как можно найти самый длинный путь между двумя вершинами?Пробовала создать еще один массив, проделать все тоже самое что и с массивом С,только сделать отдельное условие if с противоположным знаком,в итоге выводит только начальную и последнюю вершину
Вероника99 вне форума Ответить с цитированием
Старый 03.02.2015, 20:59   #49
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Ну дык.. Тоже самое, но поменять условие в развилке
Если снова вывод пути, то и там махнуть чуть-чуть..

А можно выпендриться и проверить есть ли у нас цикл положительного веса.. Если такой имеется, то решения (для части вершин) не будет
Poma][a вне форума Ответить с цитированием
Старый 03.02.2015, 21:44   #50
Вероника99
Форумчанин
 
Регистрация: 15.12.2013
Сообщений: 414
По умолчанию

А что нужно поменять в этой программе для того,чтобы граф был представлен списком смежности? Если я ввожу список таким образом,как сделать так чтобы двумерный массив заполнился значениями из одномерного массива terminal. Часть программы взята с сайта http://kvodo.ru/adjacency-list.html
Код:
void Add(int v, int u) //добавление ребра
{
k=k+1;
terminal[k]=u;
next_el[k]=head[v];
head[v]=k;
}
//главная функция
void main()
{
setlocale(LC_ALL,"Rus");
k=0;

cout<<"Вводите смежные вершины:"<<endl;
for (i=0; i<m; i++)
{
cin>>v>>u;
Add(v, u);

cout<<endl;
}
Вероника99 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ПОстроение графа по заданным вершинам Otar4ik Общие вопросы C/C++ 6 11.09.2014 21:47
создание графа по матрице и поиск кратчайшего пути из одного графа в другой lexflax Общие вопросы C/C++ 1 06.09.2012 07:32
Построить ломаную линию по заданныи вершинам. Вершины указываются с клавиатуры по «методу резиновой нити». HollywoodStar Паскаль, Turbo Pascal, PascalABC.NET 0 17.12.2011 14:36
по заданной матрице смежности простого графа построить каркас этого графа с использованием поиска вширь d1m2o3n4 Помощь студентам 0 22.06.2011 22:43
проход по дереву на c++ Skilluser Помощь студентам 18 20.11.2010 19:34