2016-10-21 2 views
1

Общий тренд 0-1 алгоритмов BFS: если встречается край с весом = 0, то узел выдвигается на передний край дека, а если вес края равен 1, то он будет сдвинут на задний план от deque.Если ребра не вставлены в deque в отсортированном порядке весов, делает 0-1 BFS для получения правильного ответа?

Если мы случайно нажимаем края, то можем ли 0-1 BFS вычислить правильный ответ? Что, если края введены в deque, не отсортированы по порядку их весов?


Это общий алгоритм 0-1 BFS. Если я пропущу последние, если и другие части и случайным образом надавить на края, то что произойдет?

Для меня это должно сработать, но тогда почему этот алгоритм сделан таким образом?

void bfs (int start) 
{ 
    std::deque<int> Q; // double ended queue 
    Q.push_back(start); 
    distance[start] = 0;  
    while(!Q.empty()) 
    { 
     int v = Q.front(); 
     Q.pop_front(); 
     for(int i = 0 ; i < edges[v].size(); i++) 
     { 
      // if distance of neighbour of v from start node is greater than sum of 
      // distance of v from start node and edge weight between v and its 
      // neighbour (distance between v and its neighbour of v) ,then change it 
      if(distance[edges[v][i].first] > distance[v] + edges[v][i].second) 
      { 
       distance[edges[v][i].first] = distance[v] + edges[v][i].second; 

       // if edge weight between v and its neighbour is 0 
       // then push it to front of 
       // double ended queue else push it to back 
       if(edges[v][i].second == 0) 
       { 
        Q.push_front(edges[v][i].first); 
       } 
       else 
       { 
        Q.push_back(edges[v][i].first); 
       } 
      } 
     } 
    } 
} 

ответ

1

Все дело в производительности. Хотя случайная вставка все еще находит самый короткий путь, вам нужно рассмотреть гораздо больше путей (экспоненциальных по размеру графика). Таким образом, структурированная вставка гарантирует линейную временную сложность. Начнем с того, почему 0-1 BFS гарантирует эту сложность.

Основная идея такая же, как и алгоритм Дейкстры. Вы посещаете узлы, упорядоченные по их расстоянию от начального узла. Это гарантирует, что вы не обнаружите края, которые уменьшат расстояние до наблюдаемого до сих пор узла (что потребовало бы, чтобы вы снова вычислили весь подграф).

В 0-1 BFS, вы начинаете с начальным узлом и расстояние в очереди просто:

d = [ 0 ] 

Тогда вы считаете все сосед. Если вес края равен нулю, вы нажимаете его на передний, если он один, а затем назад. Итак, вы получаете такую ​​же очередь:

d = [ 0 0 0 1 1] 

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

d = [ 0* 0* 0 0 1 1 1*] 

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

d = [ 1 1 1 1 1 ] 

Переход от первого узла в течение нулевого веса края производит общую длину пути, равный 1. Переходя один весом краевых результатов через пополам. Так делать 0-1 BFS, вы получите:

d = [ 1* 1* 1 1 1 1 2* 2*] 

И так далее ... Так что заключение, процедура необходима, чтобы убедиться, что вы посещаете узлы в порядке их расстояния до начального узла. Если вы сделаете это, вы будете рассматривать каждый ребро только дважды (один раз в прямом направлении, один раз в обратном направлении). Это связано с тем, что при посещении узла вы знаете, что вы не можете снова попасть на узел с меньшим расстоянием. И вы рассматриваете только края, исходящие от узла, когда вы его посещаете. Поэтому, даже если узел снова добавляется в очередь одним из его соседей, вы не будете посещать его, потому что результирующее расстояние не будет меньше текущего. Это гарантирует сложность времени O (E), где E - количество ребер.

Итак, что произойдет, если вы не посетите узлы, упорядоченные по их расстоянию от начального узла?Фактически, алгоритм все равно найдет кратчайший путь. Но он рассмотрит гораздо больше путей. Предположим, что вы посетили узел, и этот узел снова помещен в очередь одним из его соседей. На этот раз мы не можем гарантировать, что полученное расстояние не будет меньше. Таким образом, нам может понадобиться снова посетить его и снова поставить всех своих соседей в очередь. То же самое относится и к соседям, поэтому в худшем случае это может распространяться по всему графику, и вы снова и снова посещаете узлы. В конечном итоге вы найдете решение, потому что вы всегда уменьшаете расстояние. Но необходимое время намного больше, чем для смарт-BFS.