Encontrar kth-caminos más cortos?


Encontrar el camino más corto entre dos puntos en un gráfico es una pregunta de algoritmos clásicos con muchas buenas respuestas (algoritmo de Dijkstra, Bellman-Ford , etc. Mi pregunta es si hay un algoritmo eficiente que, dado un gráfico dirigido y ponderado, un par de nodos s y t, y un valor k, encuentra el camino k-ésimo más corto entre s y t. En el caso de que haya múltiples caminos de la misma longitud que todos se unen para el k-ésimo más corto, está bien que el algoritmo devuelve cualquiera de ellos.

Sospecho que este algoritmo probablemente se puede hacer en tiempo polinómico, aunque soy consciente de que podría haber una reducción del problema longest path que lo haría NP-difícil.

¿Alguien sabe de tal algoritmo, o de una reducción que muestre que es NP-hard?

Author: Bo Persson, 2011-08-26

3 answers

El mejor algoritmo (y básicamente óptimo) se debe a Eppstein.

 9
Author: comestibles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-26 19:41:33

Estás buscando el algoritmo de Yen para encontrar K caminos más cortos. El k camino más corto será entonces el último camino en ese conjunto.

Aquí está una implementación del algoritmo de Yen.

Y aquí está el documento original describiéndolo.

 10
Author: tskuzzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-26 18:07:48

Aunque la pregunta tiene una respuesta válida aceptada, esta respuesta aborda el problema de la implementación proporcionando un código de trabajo de ejemplo. Encuentre el código válido para kth shortest path aquí:

// Complejidad temporal: O(Vk (V*logV + E))

using namespace std;

typedef long long int ll;
typedef short int i16;
typedef unsigned long long int u64;
typedef unsigned int u32;
typedef unsigned short int u16;
typedef unsigned char u8;

const int N = 128;

struct edge
{
    int to,w;
    edge(){}
    edge(int a, int b)
    {
        to=a;
        w=b;
    }
};

struct el
{
    int vertex,cost;
    el(){}
    el(int a, int b)
    {
        vertex=a;
        cost=b;
    }
    bool operator<(const el &a) const
    {
        return cost>a.cost;
    }
};

priority_queue <el> pq;

vector <edge> v[N];

vector <int> dist[N];

int n,m,q;

void input()
{
    int i,a,b,c;
    for(i=0;i<N;i++)
        v[i].clear();
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d", &a, &b, &c);
        a++;
        b++;
        v[a].push_back(edge(b,c));
        v[b].push_back(edge(a,c));
    }
}

void Dijkstra(int starting_node, int ending_node)
{
    int i,current_distance;
    el curr;
    for(i=0;i<N;i++)
        dist[i].clear();
    while(!pq.empty())
        pq.pop();
    pq.push(el(starting_node,0));
    while(!pq.empty())
    {
        curr=pq.top();
        pq.pop();
        if(dist[curr.vertex].size()==0)
            dist[curr.vertex].push_back(curr.cost);
        else if(dist[curr.vertex].back()!=curr.cost)
            dist[curr.vertex].push_back(curr.cost);
        if(dist[curr.vertex].size()>2)
            continue;
        for(i=0;i<v[curr.vertex].size();i++)
        {
            if(dist[v[curr.vertex][i].to].size()==2)
                continue;
            current_distance=v[curr.vertex][i].w+curr.cost;
            pq.push(el(v[curr.vertex][i].to,current_distance));
        }
    }
    if(dist[ending_node].size()<2)
        printf("?\n");
    else
        printf("%d\n", dist[ending_node][1]);
}

void solve()
{
    int i,a,b;
    scanf("%d", &q);
    for(i=1;i<=q;i++)
    {
        scanf("%d %d", &a, &b);
        a++;
        b++;
        Dijkstra(a,b);
    }
}

int main()
{
    int i;
    for(i=1;scanf("%d %d", &n, &m)!=EOF;i++)
    {
        input();
        printf("Set #%d\n", i);
        solve();
    }
    return 0;
}
 -1
Author: Aditya C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-19 22:56:16