2010-10-28 13 views
3

J'ai un graphe DAG non pondéré. Ce que je veux faire est de trouver tous les chemins d'une manière gourmande et le chemin doit contenir au moins K nœuds, et un nœud de départ donné.Recherche de trajectoires dans un graphe orienté avec approche gourmande avec au moins K nœuds et un nœud de départ donné

Y a-t-il un algorithme/une implémentation existant qui fait cela?

Par exemple, j'ai le graphique suivant:

my %graph =(36=>[31],31=>[30,22],30=>[20],22=>[20,8],20=>[1],8=>[5],5=>[2],2=>[1,20]); 

alt text

Donc, si je définis K = 5 et noeud de départ 36, j'espère obtenir:

{1,20,22,31,36} 
{1,20,2,5,8,22,31,36} 
{1,20,30,31,36} 
{1,2,5,8,22,31,36} 
+0

J'ai l'impression que le nombre de ces chemins peut croître de façon exponentielle sur le nombre de nœuds. Comment feriez-vous face à cela? – Leonid

+0

@Leonid: Je le ferai avec heuristique, par exemple. suppression de certains nœuds avec certaines conditions (spécifique au domaine). – neversaint

+1

Le fait de revenir en arrière ne résoudrait pas votre problème? Une approche plus rapide que je voudrais envisager est de penser au problème en termes de programmation dynamique, compte tenu des conditions spécifiques au domaine qui peuvent être appliquées. Sans ces conditions, il ne semble pas qu'il y ait quelque chose de mieux que de revenir en arrière. – Leonid

Répondre

1

Ce n'est pas très difficile.

use warnings; 
use strict; 
use Data::Dumper; 

my @stack =(); 

my %graph = (36=>[31],31=>[30,22],30=>[20],22=>[20,8], 
      20=>[1],8=>[5],5=>[2],2=>[1,20]); 

# add begin to stack 
push(@stack, { node => 36, way => [36] }); 

while (@stack > 0) { 

    my $node = pop(@stack); 

    # way 
    my $way = $node->{way}; 

    # complete way 
    if ($node->{node} == 1) { 
     print Dumper($node->{way}); 
    } 

    # add next nodes 
    my $nextArr = $graph{$node->{node}}; 

    for my $nextNod (@$nextArr) { 
     # add way 
     my @tmpWay = @$way; 
     push(@tmpWay, $nextNod); 

     # add to stack 
     push(@stack, { node => $nextNod, way => \@tmpWay }); 
    } 
} 

Vous pouvez donc tester, si le nœud est le noeud final et enregistrer tous les chemins. Vous devez Optimase ce script

modifier

Ajout sans fin sauver la protection.

éditer 2

Vous n'avez pas besoin d'une protection sans fin. Ajouter shift à pop, puis vous cherchez plus d'un moyen de mettre fin à la note :)

+0

Merci J'ai un problème avec la sortie. Ces deux lignes ont donné un message d'erreur. "push (@stack, {node => 36, way => [36]})" et "while (@ # stack> 0) {". Veuillez nous conseiller – neversaint

+1

Le code fonctionne maintenant. C'était seulement du pseudo code, mais je le corrige pour toi ... J'espère que je n'ai pas fait tes devoirs. – xGhost