Самый длинный путь для взвешенного ориентированного ациклического графа

Я пытаюсь осмыслить эту проблему, а затем написать для нее код Java. Я знаю, что здесь было какое-то обсуждение, но я не вижу много ответчиков, поэтому я хотел бы повторить вопрос, записав свои мысли, и я надеюсь получить некоторую обратную связь от вас, ребята. Спасибо!

Мои мысли: для каждого конечного узла найти самый длинный путь от корневого узла к нему для всех путей найти максимальную длину пути

Однако разве это не просто грубая сила? Есть ли более элегантные решения для этого?

Я слышал об использовании алгоритма Джикстры с отрицательными весами, но в некоторых местах говорится, что это работает только в определенных случаях? Я также видел предложения по алгоритму Беллмана Форда, но разве он не используется для поиска кратчайшего пути?

Спасибо!!

2 ответа

Я думаю, что вы должны сделать, это вычислить все кратчайшие пути корня к листу и затем взять самый длинный из вычисленных путей. В общем, это было бы сложной проблемой, но, к счастью, вы используете ориентированный ациклический граф. На практике алгоритм будет работать очень хорошо из-за этого ограничения. Следующий код может вам помочь, он был разработан с yWorks и взят с этого сайта:

// To hold an edge list for every path. 
YList allShortestPaths = new YList();

// The actual number of proper shortest paths is unknown, so we start with a really great value for 'k'. 
YCursor pathCursor = ShortestPaths.kShortestPathsCursor(graph, edgeCostsDP, startNode, endNode, Integer.MAX_VALUE);
if (pathCursor.ok())
{
  // The first path between the two nodes having least costs. 
  final EdgeList firstPath = (EdgeList)pathCursor.current();
  final double costsOfFirstPath = calculateCostsForPath(firstPath, edgeCostsDP);

  allShortestPaths.add(firstPath);
  pathCursor.next();

  // Look further. 
  while (pathCursor.ok())
  {
    EdgeList currPath = (EdgeList)pathCursor.current();
    double currCosts = calculateCostsForPath(currPath, edgeCostsDP);
    // If the current path is also a proper shortest path with costs equal to those 
    // of the first path, then add it to the list. 
    if (!(currCosts > costsOfFirstPath))
    {
      allShortestPaths.add(currPath);
      pathCursor.next();
    }
    else
      break;
  }
}

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

Пусть индексы вершин после топосорта равны 0,1,2,....,n-1 (всего n вершин в графе)

Пусть F [i] будет значением самого длинного пути, который заканчивается в вершине i.

Тогда для каждого исходящего ребра от i до всех j мы можем обновить F[j] как F[j]=max(F[j],F[i]+1)

Мы можем начать с инициализации всех F [i] в ​​ноль. Затем цикл от i=1 до n-1.

Окончательный ответ будет max{F[i]} 0<=i<=n-1

Другие вопросы по тегам