Dijkstra

Fermé
Bonjour,

Je recherche l'algorithme de dijkstra en Matalab pour trouver le plus court chemin dans une matrice du point (i,j) au point (k,l).

Merci d'avance

7 réponses

  1. Voila une version de l'algo de dijkstra.
    elle marche parfaitement!
    Je crois qu avec ta méthode tu t'égares un peu...
    Keep It Simple Stupid!
    Ce fichier est naturellement copyrighté, donc si tu veux l'utiliser
    pour qquechose de public ou privé tu dois raquer!

    tchaou!

    function D = dijk(A,s,t)
    % dijk - shortest paths from nodes 's' to nodes 't' using Dijkstra algorithm.
    %
    %   D = dijk(A,s,t);
    %
    %     A = n x n node-node weighted adjacency matrix of arc lengths
    %         (Note: A(i,j) = 0   => Arc (i,j) does not exist;
    %                A(i,j) = NaN => Arc (i,j) exists with 0 weight)
    %     s = FROM node indices
    %       = [] (default), paths from all nodes
    %     t = TO node indices
    %       = [] (default), paths to all nodes
    %     D = |s| x |t| matrix of shortest path distances from 's' to 't'
    %       = [D(i,j)], where D(i,j) = distance from node 'i' to node 'j' 
    %
    %	(If A is a triangular matrix, then computationally intensive node
    %   selection step not needed since graph is acyclic (triangularity is a 
    %   sufficient, but not a necessary, condition for a graph to be acyclic)
    %   and A can have non-negative elements)
    %
    %	(If |s| >> |t|, then DIJK is faster if DIJK(A',t,s) used, where D is now
    %   transposed and P now represents successor indices)
    %
    %  (Based on Fig. 4.6 in Ahuja, Magnanti, and Orlin, Network Flows,
    %   Prentice-Hall, 1993, p. 109.)
    
    % Copyright (c) 1998-2000 by Michael G. Kay
    % Matlog Version 1.3 29-Aug-2000
    % 
    %  Modified by JBT, Dec 2000, to delete paths
    % Modified by AFELT 2004
    
    
    % Input Error Checking ******************************************************
    error(nargchk(1,3,nargin));
    
    [n,cA] = size(A);
    
    if nargin < 2 | isempty(s), s = (1:n)'; else s = s(:); end
    if nargin < 3 | isempty(t), t = (1:n)'; else t = t(:); end
    
    if ~any(any(tril(A) ~= 0))			% A is upper triangular
       isAcyclic = 1;
    elseif ~any(any(triu(A) ~= 0))	% A is lower triangular
       isAcyclic = 2;
    else										% Graph may not be acyclic
       isAcyclic = 0;
    end
    
    if n ~= cA
       error('A must be a square matrix');
    elseif ~isAcyclic & any(any(A < 0))
       error('A must be non-negative');
    elseif any(s < 1 | s > n)
       error(['''s'' must be an integer between 1 and ',num2str(n)]);
    elseif any(t < 1 | t > n)
       error(['''t'' must be an integer between 1 and ',num2str(n)]);
    end
    % End (Input Error Checking) ************************************************
    
    A = A';		% Use transpose to speed-up FIND for sparse A
    
    D = zeros(length(s),length(t));
    P = zeros(length(s),n);
    
    for i = 1:length(s)
       j = s(i);
       
       Di = Inf*ones(n,1); Di(j) = 0;
       
       isLab = logical(zeros(length(t),1));
       if isAcyclic ==  1
          nLab = j - 1;
       elseif isAcyclic == 2
          nLab = n - j;
       else
          nLab = 0;
          UnLab = 1:n;
          isUnLab = logical(ones(n,1));
       end
       
       while nLab < n & ~all(isLab)
          if isAcyclic
             Dj = Di(j);
          else	% Node selection
             [Dj,jj] = min(Di(isUnLab));
             j = UnLab(jj);
             UnLab(jj) = [];
             isUnLab(j) = 0;
          end
          
          nLab = nLab + 1;
          if length(t) < n, isLab = isLab | (j == t); end
          
          [jA,kA,Aj] = find(A(:,j));
          Aj(isnan(Aj)) = 0;
                
          if isempty(Aj), Dk = Inf; else Dk = Dj + Aj; end
          
          P(i,jA(Dk < Di(jA))) = j;
          Di(jA) = min(Di(jA),Dk);
          
          if isAcyclic == 1			% Increment node index for upper triangular A
             j = j + 1;
          elseif isAcyclic == 2	% Decrement node index for lower triangular A
             j = j - 1;
          end
          
          %disp( num2str( nLab ));
       end
       D(i,:) = Di(t)';
    end
    
    3
    1. Merci quand même mais à chercher algo-info ou algoinfo ou .... je risque d'y passer beaucoup de temps
      1
      1. oui mais même les feignants doivent savoir utiliser le web ou google ... ;-)
        0
    2. Ce site n'existe pas
      0
      1. bjr je recherche l'algorithme de plus cour chemin entre les ville d'algerie (algorithme de dijkstra
        0
    3. Salut

      Ce que tu cherches, c'est l'algorithme, ou un programme Matlab ?
      Parce que je peux t'expliquer l'algo de Dijkstra (aussi appelé de Moore, si tu veux faire des recherches sur le net), mais ça n'a rien à voir avec Matlab (et pas grand-chose avec les matrices, mais c'est parce que matlab n'utilise que ça...) :

      Le but est de trouver le chemin optimal dans un graphe valué.
      Allez hop ! Je suis lancé -> c'est parti pour la théorie ;-)

      graphe G=(X,U)
      valuation U -> R
      u ->v(u)
      pb : Trouver dans G un chemin µ allant de AeX à BeX ("e" pour l'appartenance, bien sûr !) tq somme sur ueµ des v(u) soit optimale

      Soit dit en passant : l'algorithme le plus classique s'appelle Bellman, mais j'imagine que t'as tes raisons pour vouloir Dijkstra

      hypothèse supplémentaire : "c" une valuation, "s" un point de départ, et c: U -> R+ (pas de coût négatif)
      On va noter P les sommets traités définitivement, T les sommets dont l'estimation est temporaires, Pi la fonction qui à un sommet associe le coût minimal pour y parvenir, A la fonction qui à un sommet associe son prédecesseur par le + court chemin.

      Encore une hypothèse : Pi(x) = c(s,x) si (s,x)eU, mais infini sinon (initialement).

      Initialement toujours, Pi(s)=0, P={s}, T=X\{s}, A(s)=epsilon (rien)

      Algo :
      Tant que T non vide faire
      soit x0eT tq Pi(x0)=min des Pi(x) pour xeT
      T=T\{x0}, P=P U(union) {x0}
      Pour tout xeT faire
      Si Pi(x)>Pi(x0)+c(x0,x) alors
      Pi(x)=Pi(x0)+c(x0,x)
      A(x)=x0
      fin si
      fin pour
      fin TQ

      On obtient dans Pi les valeurs des plus courts chemins pour chaque point d'arrivée, et pour retrouver le chemin, il suffit de remonter les A.
      Le tout en un temps max égal au nb de sommets.

      Bon courage pour le codage

      Eléctions : Bush filled his SOUl with HOpe
      0
      1. salut , es que tu peux m'aider a realiser l'algo de dijkstra en c tt ca en utilisant des matrices merci
        ps: j'ai vraiment besoin d'aide
        0
      2. @spamwareSalut,

        L'algorithme est déjà décrit dans les différents posts, il y a même le programme un peu plus bas...

        Il y a quelque chose que tu n'as pas compris ? On ne peut t'aider que si tu poses des questions précises !
        0
    4. En tout cas merci de te donner tant de mal mais j'avais déjà toutes ces infos et d'ailleurs j'ai commencé une ébauche sous matlab. J'arrive à avoir facilement une matrice représentant les coûts de chaque points par rapport aux points adjacents et je me suis inspiré des sites suivants :
      http://www.europainternet.info/mmqos/index.php/Sujet/toms
      http://fr.freepedia.org/Algorithme_de_Dijkstra.html
      mais surtout de celui-ci :
      http://icosaweb.ac-reunion.fr/Algorithmes/Graphes/Docs/AlgorithmeDijkstra.pdf
      Mon problème est que je n'arrive pas à cumuler les coûts jusqu'à la balise. Voici mon code :

      clear all
      clc
      a=[4 8 7 5 10;2 4 7 8 4;6 4 1 2 7;2 3 1 4 9;3 5 4 1 2];
      disp(a);
      dim=max(size(a));
      absdepart=2; %abscisse balise de départ
      orddepart=2; %ordonnée balise de départ
      absarrivee=5; %abscisse balise de départ
      ordarrivee=5; %ordonnée balise d'arrivée
      for i=1:dim*dim
      for j=1:dim*dim
      b(i,j)=0;
      end;
      end;

      % creation du vecteur comportant le nombre d'éléments
      for k=1:dim*dim
      numero(1,k)=k;
      end;

      abscisse=[];
      ordonnee=[];
      poids=[];
      num=max(numero);

      for i=1:dim
      for j=1:dim
      abscisse=[abscisse,i];
      ordonnee=[ordonnee,j];
      poids=[poids,a(i,j)];
      end;
      end;
      % disp(poids);

      % quel est le numero de la balise de départ dans le vecteur numero et
      % affectation à numtest
      for numtest=1:num
      if abscisse(numtest)==absdepart
      if ordonnee(numtest)==orddepart
      break;
      end;
      end;
      end;

      % quel est le numero de la balise de fin dans le vecteur numero et
      % affectation à numfin
      for numfin=1:num
      if abscisse(numfin)==absarrivee
      if ordonnee(numfin)==ordarrivee
      break;
      end;
      end;
      end;

      disp(numtest);
      disp(numfin);
      numero(1,numtest)=0;

      % test de tous les points adjacents à la balise
      for nbretest=1:num
      if abscisse(nbretest)~=absdepart | ordonnee(nbretest)~=orddepart
      if abs(abscisse(nbretest)-abscisse(numtest))<2
      if abs(ordonnee(nbretest)-ordonnee(numtest))<2
      %poidsmodif(nbretest)=poids(nbretest)+poids(numtest);
      %b(numtest,nbretest)=poids(nbretest)+poids(numtest);
      b(numtest,nbretest)=poids(nbretest);
      %numero(1,nbretest)=0;
      else
      b(numtest,nbretest)=inf;
      end;
      else
      b(numtest,nbretest)=inf;
      end;
      else
      b(numtest,nbretest)=inf;
      end;
      end;

      %test de tous les points adjacents aux précédents sauf balise et points
      %adjacents précédents
      for nbre=1:numfin
      for nbretest=1:numfin
      if b(nbretest,nbre)~=inf
      if numero(nbretest)~=0
      if abscisse(nbretest)~=abscisse(nbre) | ordonnee(nbretest)~=ordonnee(nbre)
      if abs(abscisse(nbretest)-abscisse(nbre))<2
      if abs(ordonnee(nbretest)-ordonnee(nbre))<2
      b(nbre,nbretest)=poids(nbretest);
      %numero(1,nbre)=0;
      else
      b(nbre,nbretest)=inf;
      end;
      else
      b(nbre,nbretest)=inf;
      end;
      else
      b(nbre,nbretest)=inf;
      end;
      else
      b(nbre,nbretest)=inf;
      end;
      else
      b(nbre,nbretest)=inf;
      end;
      end;
      end;

      disp(b);
      disp(numero);

      J'ai aussi récupérer celà mais je ne comprends pas le résultat obtenu :

      function D = dijkstra(A,s,t)
      % dijk - shortest paths from nodes 's' to nodes 't' using Dijkstra algorithm.
      %
      % D = dijk(A,s,t);
      %
      % A = n x n node-node weighted adjacency matrix of arc lengths
      % (Note: A(i,j) = 0 => Arc (i,j) does not exist;
      % A(i,j) = NaN => Arc (i,j) exists with 0 weight)
      % s = FROM node indices
      % = [] (default), paths from all nodes
      % t = TO node indices
      % = [] (default), paths to all nodes
      % D = |s| x |t| matrix of shortest path distances from 's' to 't'
      % = [D(i,j)], where D(i,j) = distance from node 'i' to node 'j'
      %
      % (If A is a triangular matrix, then computationally intensive node
      % selection step not needed since graph is acyclic (triangularity is a
      % sufficient, but not a necessary, condition for a graph to be acyclic)
      % and A can have non-negative elements)
      %
      % (If |s| >> |t|, then DIJK is faster if DIJK(A',t,s) used, where D is now
      % transposed and P now represents successor indices)
      %
      % (Based on Fig. 4.6 in Ahuja, Magnanti, and Orlin, Network Flows,
      % Prentice-Hall, 1993, p. 109.)

      % Copyright (c) 1998-2000 by Michael G. Kay
      % Matlog Version 1.3 29-Aug-2000
      %
      % Modified by JBT, Dec 2000, to delete paths

      % Input Error Checking ******************************************************
      error(nargchk(1,3,nargin));

      [n,cA] = size(A);

      if nargin < 2 | isempty(s), s = (1:n)'; else s = s(:); end
      if nargin < 3 | isempty(t), t = (1:n)'; else t = t(:); end

      if ~any(any(tril(A) ~= 0)) % A is upper triangular
      isAcyclic = 1;
      elseif ~any(any(triu(A) ~= 0)) % A is lower triangular
      isAcyclic = 2;
      else % Graph may not be acyclic
      isAcyclic = 0;
      end

      if n ~= cA
      error('A must be a square matrix');
      elseif ~isAcyclic & any(any(A < 0))
      error('A must be non-negative');
      elseif any(s < 1 | s > n)
      error(['''s'' must be an integer between 1 and ',num2str(n)]);
      elseif any(t < 1 | t > n)
      error(['''t'' must be an integer between 1 and ',num2str(n)]);
      end
      % End (Input Error Checking) ************************************************

      A = A'; % Use transpose to speed-up FIND for sparse A

      D = zeros(length(s),length(t));
      P = zeros(length(s),n);
      for i = 1:length(s)
      j = s(i);

      Di = Inf*ones(n,1); Di(j) = 0;

      isLab = logical(zeros(length(t),1));
      if isAcyclic == 1
      nLab = j - 1;
      elseif isAcyclic == 2
      nLab = n - j;
      else
      nLab = 0;
      UnLab = 1:n;
      isUnLab = logical(ones(n,1));
      end

      while nLab < n & ~all(isLab)
      if isAcyclic
      Dj = Di(j);
      else % Node selection
      [Dj,jj] = min(Di(isUnLab));
      j = UnLab(jj);
      UnLab(jj) = [];
      isUnLab(j) = 0;
      end

      nLab = nLab + 1;
      if length(t) < n, isLab = isLab | (j == t); end

      [jA,kA,Aj] = find(A(:,j));
      Aj(isnan(Aj)) = 0;

      if isempty(Aj), Dk = Inf; else Dk = Dj + Aj; end

      P(i,jA(Dk < Di(jA))) = j;
      Di(jA) = min(Di(jA),Dk);

      if isAcyclic == 1 % Increment node index for upper triangular A
      j = j + 1;
      elseif isAcyclic == 2 % Decrement node index for lower triangular A
      j = j - 1;
      end

      %disp( num2str( nLab ));
      end
      D(i,:) = Di(t)';
      end

      encore merci de ton aide matlab
      0
      1. function [p, pred] = dijkstra (n , C)
        %n l'orde du graphe, C matrice des couts , p cout , pred : le chemin
        S = 1 ;
        T = 2 : n ;
        p = C(1,:);
        pred = Zeros (1,n);
        T1 = find( ( C (1, :) > 0 & ( C(1,:)< Inf) )
        pred(T1) = 1;
        while( isempty(T) == 0 )
        l = [ p(T)' T')
        [m,e] = min ( l(:,1));
        k = l(e,2);
        S = [s,k];
        T(e) = [] % supression du e eme element
        T2 = find( ( C( k,:) > 0) & ( C ( k, : ) <Inf ) ) ;
        for i : T3
        if ( p(i ) > p(k) + C( k,i ) )
        p( i ) = p( k ) + C (k,i ) ;
        pred( i ) = k ;
        end
        end

        end

        end

        je suis pas si sûr que ca :)
        0