Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> находнение всех путей в графе 
:(
    Опции темы
xber9
Дата 2.11.2012, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



увы но как  я и говорил код не мой
PM MAIL   Вверх
baldina
Дата 2.11.2012, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



обобщенный поиск в ширину
Код

function bfs ($graph, $node, $current) {
 $queue[] = array(null,$node);
 $marks[$node] = true;
 while (count($queue) > 0) {
   list($v,$u) = array_shift ($queue);
   if (is_callable ($current))
     $current ($v,$u);
   foreach (get_adjacent ($graph, $u) as $w)
     if (!$marks[$w]) {
       $marks[$w] = true;
       $queue[] = array($u,$w);
     }
 }
}

эта функция не зависит от представления графа, для адаптации к конкретному представлению служит функция get_adjacent ();
реализация bfs не самая общая, но достаточная для наших целей: для каждой посещенной вершины вызывается пользовательская функция-посетитель $current(), куда передается ребро (текущая вершина и та, из которой мы сюда пришли).

реализация функции-посетителя для алгоритма поиска кратчайщих путей по Дейкстре:
Код

function dijkstra_visitor ($v, $u) {
  global $cost, $path;
  if (!isset($cost[$u]) || $cost[$u] > $cost[$v]+1) {
    $cost[$u] = $cost[$v]+1;
    if ($v)
      $path[$u] = $path[$v];
    $path[$u][] = $u;
  }
}

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

что бы применить это к вашей структуре нужен адаптер. в данном случае он тривиален:
Код

function get_adjacent ($graph, $v) {
  return isset($graph[$v]) ? $graph[$v] : array();
}


ну вот и все, остальное самостоятельно допилите
http://codepad.org/d2eGCrci
PM MAIL   Вверх
baldina
Дата 2.11.2012, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(xber9 @  31.10.2012,  13:44 Найти цитируемый пост)
я вижу это так, что сначала мне надо  получить все возможные пути из А в Б  а потом их проверять на наличие пересадок 

для минимизации пересадок измените вес для пересадки (уже говорили про это)
Цитата(baldina @  2.11.2012,  18:58 Найти цитируемый пост)
$cost[$u] > $cost[$v]+1


кстати, вам нужно минимум пересадок или минимальное время?
PM MAIL   Вверх
xber9
Дата 2.11.2012, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



огромное спаисбо зхавтар буду разбираться
если что  надеюсь поможете но думаю все норм еще рас спс

Добавлено @ 20:08
Цитата(baldina @  2.11.2012,  20:04 Найти цитируемый пост)

кстати, вам нужно минимум пересадок или минимальное время? 


вообще то и то  и то в зависимости  от выбора пользователя 
кстати как правельно задать  веса для пересадок?
как отдельный массив ? и проверять принадлежит ли дуга VU этому массиву и если да то  делатть не +1 а +много или как?

Это сообщение отредактировал(а) xber9 - 2.11.2012, 23:54
PM MAIL   Вверх
baldina
Дата 3.11.2012, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(xber9 @  2.11.2012,  20:05 Найти цитируемый пост)
 как правельно задать  веса для пересадок?

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

но если вводить вес, программу придется немного переделать: мой dijkstra_visitor() по сути relax_visitor(), они совпадают для невзвешенного графа, а для взвешенного графа dfs  bfs с обычной очередью недостаточно, нужно иметь очередь с приоритетами.

Добавлено @ 13:39
Цитата(xber9 @  2.11.2012,  20:05 Найти цитируемый пост)
проверять принадлежит ли дуга VU этому массиву и если да то  делатть не +1 а +много

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

Это сообщение отредактировал(а) baldina - 3.11.2012, 14:27
PM MAIL   Вверх
xber9
Дата 3.11.2012, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



Цитата(baldina @  3.11.2012,  13:32 Найти цитируемый пост)

но если вводить вес, программу придется немного переделать: мой dijkstra_visitor() по сути relax_visitor(), они совпадают для невзвешенного графа, а для взвешенного графа dfs с обычной очередью недостаточно, нужно иметь очередь с приоритетами. 


извиняюсь но я практически ничего не понял  из этой фразы
где об этом можно почитать или может если для вас это не слишком затруднительно покажете как изменить ваш  пример ( конечно если не об очень многом прошу)
еще рас прошу прощения если очень сильно напрягаю и туплю  smile

Добавлено @ 13:48
Цитата(baldina @  3.11.2012,  13:32 Найти цитируемый пост)
более правильно, думаю, задавать веса для всех ребер (значения времени в минутах, например), включая время пересадок. 

идея со временем   кажется самое то  тк время пути тоже надо будет  подсчитывать

я  так понимаю вы предлагаете изменить исходные данные типа так
Код

$graph = array(
      55  => array(60=> array(3)),
      60  => array(55=> array(3),74=> array(4)),
      74  => array(60=> array(3),75=> array(6)),
...........


но тогда как менять фунцию ибо я как всегда не понимаю (не хватает математических знаний как я пологаю)

Это сообщение отредактировал(а) xber9 - 3.11.2012, 13:50
PM MAIL   Вверх
baldina
Дата 3.11.2012, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



да, фраза не очень понятная))) и с ошибкой: не dfs, а bfs - поиск в ширину
в поиске в ширину в очередь заносятся смежные вершины, потом из очереди вынимаются и обрабатываются. если весов нет, длина пути соответствует числу проходимых вершин
если веса есть, нужно из очереди выбирать вершину с наименьшим весом(приоритетом), поэтому требуется очередь с приоритетами (это и будет алгоритм дейкстры).
в любом алгоритме поиска кратчайших путей (в т.ч. в простейшем на основе поиска в ширину) используется т.н. функция relax для релаксирования путей, т.е. поддержания списка кратчайших путей и их весов.
для очередей с приоритетами в php можно использовать класс SplMinHeap
Цитата(xber9 @  3.11.2012,  13:41 Найти цитируемый пост)
где об этом можно почитать

любая книга по алгоритмам,
http://en.wikipedia.org/wiki/Breadth-first_search
http://ru.wikipedia.org/wiki/%D0%90%D0%BB%...%82%D1%80%D1%8B

Цитата(xber9 @  3.11.2012,  13:41 Найти цитируемый пост)
      55  => array(60=> array(3)),

да, что-то типа этого.

Добавлено через 1 минуту и 9 секунд
будет время, попробую написать, но позже...
PM MAIL   Вверх
xber9
Дата 3.11.2012, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



Цитата(baldina @  3.11.2012,  14:43 Найти цитируемый пост)

будет время, попробую написать, но позже... 

если будет возможность напишите плиз  ибо сам я не уверен что до конца разберусь
PM MAIL   Вверх
baldina
Дата 4.11.2012, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



вот http://codepad.org/OoaxvDF9
это многословнее, чем раньше, но подходит для адаптации к разным представлениям графа и алгоритмам

Добавлено через 8 минут и 34 секунды
кстати, простейшая модификация первой реализации для работы с весами - просто перенести вызов $current:
Код

function bfs ($graph, $node, $current) {
 $queue[] = array(null,$node);
 $marks[$node] = true;
 while (count($queue) > 0) {
   list($v,$u) = array_shift ($queue);
   // $current ($v,$u);
   foreach (get_adjacent ($graph, $u) as $w)
     $current ($u,$w);
     if (!$marks[$w]) {
       $marks[$w] = true;
       $queue[] = array($u,$w);
     }
 }
}

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

PM MAIL   Вверх
xber9
Дата 4.11.2012, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



Цитата(baldina @  4.11.2012,  12:24 Найти цитируемый пост)
вот http://codepad.org/OoaxvDF9
это многословнее, чем раньше, но подходит для адаптации к разным представлениям графа и алгоритмам



большое спасибо очень выручил- буду постепенно разбираться
я правельно понимаю что для того чтобы  считался путь с минимумом пересадок достаточно значительно увеличить  вес пересадки а чтобы  искал просто кратчайший путь то надо обратно уменьшить вес

и еще вопрос ( так как еще не разобрался) как вывести на печать общий вес пути from - to
PM MAIL   Вверх
baldina
Дата 4.11.2012, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(xber9 @  4.11.2012,  16:54 Найти цитируемый пост)
я правельно понимаю что для того чтобы  считался путь с минимумом пересадок достаточно значительно увеличить  вес пересадки а чтобы  искал просто кратчайший путь то надо обратно уменьшить вес

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

Цитата(xber9 @  4.11.2012,  16:54 Найти цитируемый пост)
вывести на печать общий вес пути from - to 

содержится в 
Код

$this->cost[$to];


PM MAIL   Вверх
xber9
Дата 4.11.2012, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



Цитата(baldina @  4.11.2012,  17:35 Найти цитируемый пост)
да. 
кстати, минимум пересадок может давать очень плохие пути. например, динамо-савеловская через тверскую. даже бабушка так не поедет.

я понимаю поэтому буду давать пользователю выбор   как ему  посчитать
мин времени или мин пеерсадок
>динамо-савеловская через тверскую 
я поеду так как инвалиду легче  дальше проезхать   чем ходить по переходам)
еще рас спасибо
PM MAIL   Вверх
xber9
Дата 4.11.2012, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



НЕ охото начинать новую тему поэтому спрошу тут
переделал данные вот так
Код

$t0=1;
$t1=2;
$t2=3;
$t3=4;
$t4=5;
    
    // определяем граф
    $graph = array(
    63  => array(153=>$t2,62=>3,47=>2),
     48  => array(47=>2,52=>$t1,53=>$t2, 152=>2),
);

 где t1....t4 времена ( веса) для пересадок
далее при определнных условиях я делаю так
Код


if(<пользователь выбирает мин пересадок>){

$t0=100;
$t1=100;
$t2=100;
$t3=100;
$t4=100;

<расчет пути>

}



однако данные внутри описания графа ($graph)  отсались прежними а не =100

вопрос как переинициализоваровать граф чтобы  туда записались сотни ( надеюсь понятно  обьяснил)


Это сообщение отредактировал(а) xber9 - 4.11.2012, 23:22
PM MAIL   Вверх
xber9
Дата 4.11.2012, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 21.1.2007

Репутация: нет
Всего: нет



или как по другому изменять веса для пересадок при определенных условиях
PM MAIL   Вверх
baldina
Дата 5.11.2012, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



ситуация аналогична такой:

Код

$a=1;
$b=$a;

if (...) {
  $a = 2;
  // и тут мы с удивлением обнаруживаем что $b не изменилось)))
}


варианты решения:
Код

$b=1;
if (...) {
  $b = 2;
}


Код

$a=1;
$b=&$a; // по ссылке

if (...) {
  $a = 2;
  // и тут мы с радостью обнаруживаем что $b изменилось)))
}

а самый простой и правильный вариант вероятно такой:
Код

$a=1;
if (...) {
  $a = 2;
}
$b=$a; 


PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.0579 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.