Rastgele dizi, kısa yoldan diğer düğümlere bağlı düğümleri ile Linear Array

4 Cevap php

INFO: I have an Array of 100 nodes, [ 0 .. 99 ]. Each node can have an arbitrary number of linked nodes:

eg1, 0 links to 5, 10, 15, 20. eg2, 1 links to 30, 40, 50. eg3, etc..

Tüm 100 düğümleri en az bir bağlı düğüm var, düğümler onlara bağlayan kim bilmiyorum.

QUESTION: How can I find the shortest link-path if provided with START and END.

örn. BAŞLANGIÇ = 5, END = 80, Bağlantı Yolu (örnek): [5] -> 10 -> 24 -> 36 -> [80]?

Ben Pascal ve / veya PHP kullanarak, ama ben [code çok yardımcı] arıyorum nedir nasıl anlayış var.

4 Cevap

Bir Genişlik İlk Geçişi Başlat düğüm ile başlayan ve kısa sürede bitiş düğümü bulmak gibi çıkın etmeyin.

Bu döngüleri var mı? yani bir DAG mi?

Döngüleri yoksa:

   List<Node> GetShortestPath(Node startNode, Node endNode)
   {   
       //If this is the node you are looking for...
       if (startNode.ReferenceEquals(endNode))
       {
           //return a list with just the end node
           List<Nodes> result = new List<Nodes>();
           result.Add(endNode);            
           return result;
       }

       List<Node> bestPath = null;

       foreach(Node child in startNode.Children)
       {             
          //get the shortest path from this child
          List<Node> childPath = GetShortestPath(child, endNode);
          if (childPath != null &&
             ( bestPath == null || childPath.Count < bestPath.Count))
          { 
              bestPath = childPath;
          }
       }

       bestPath.Insert(0, startNode);
       return bestPath;
    }

[Edit: Added an example for cycles] If there can be cycles:

   List<Node> GetShortestPath(Node startNode, Node endNode)
   {
        List<Node> nodesToExclude = new List<Node>();
        return GetShortestPath(startNode, endNOde, nodesToExclude);
   }

   List<Node> GetShortestPath(Node startNode, Node endNode, List<Node> nodesToExclude)
   {   
       nodesToExclude.Add(startNode);

       List<Node> bestPath = null;

       //If this is end node...
       if (startNode.ReferenceEquals(endNode))
       {
           //return a list with just the child node
           List<Nodes> result = new List<Nodes>();
           result.Add(endNode);            
           return result;
       }

       foreach(Node child in startNode.Children)
       {
          if (!nodesToExclude.Contains(child))
          {
              //get the shortest path from this child
              List<Node> childPath = GetShortestPath(child, endNode);
              if (childPath != null &&
                 ( bestPath == null || childPath.Count < bestPath.Count))
              { 
                  bestPath = childPath;
              }
          }
       }

       nodesToExclude.Remove(startNode);
       bestPath.Insert(0, child);

       return bestPath;
    }

İki yapılar: Bir dizi ve bir liste.

Setinde, zaten ziyaret etmiş düğümleri saklayın. Bu döngüleri şu engeller.

(1) bir düğüm ve geri bulunan düğüme (2) bir işaretçi: liste içeren nesnelerin olduğunu.

Başlangıç ​​düğüm başlayarak, kümesine eklemek null geri referansla listesine ekleyin ve sonra bu listedeki endeksi 0 geri referansları ile listeye ulaşabilirsiniz tüm düğümleri (başlangıç ​​düğümü) ekleyin .

Eğer sonuna ulaşmak sonra listedeki her eleman için daha sonra, yukarı kadar, aşağıdakileri yapın:

  1. Bu sette ise zaten atlayın (sen zaten ziyaret etmiş) ve listedeki bir sonraki öğeye geçmek.
  2. aksi halde, kümesine eklemek, ve bu listenin sonuna 'bakıyor' olan indeksine geri referansları ile listeye ulaşabilirsiniz tüm düğümleri ekleyin. Sonra listesi ve tekrarı bir sonraki dizine gidin.

Herhangi bir noktada (sen listeye ekliyoruz optimum gibi - listede ziyaret aksine) son düğümü ulaşırsanız, geri başlangıç ​​düğüme geri referanslar yoluyla izlemek ve yolu ters.

Örnek:

Given nodes 0 through 3, where
node0 --> node1
node0 --> node2
node1 --> node2
node2 --> node3
and node0 is START and node3 is END

SET = {}
LIST = []

Adım 1 - BAŞLANGIÇ ekleyin:

SET = {node0}
LIST = [[node0, null]]

Adım 2 - listesinin dizin 0 - ulaşılabilir düğümleri ekleyin:

SET = {node0, node1, node2}
LIST = [[node0, null], [node1, 0], [node2, 0]]

Adım 3 - LİSTESİ indeksi 1 - ulaşılabilir düğümleri ekleyin:

node2 is already in the SET. skip adding reachable nodes to LIST.
SET = {node0, node1, node2}
LIST = [[node0, null], [node1, 0], [node2, 0]]

Adım 4 - LİSTESİ dizin 2'deki - ulaşılabilir düğümleri ekleyin:

SET = {node0, node1, node2, node3}
LIST = [[node0, null], [node1, 0], [node2, 0], [node3, 2]]

Adım 5 - SON ulaştı, şimdi geriye:

LİSTESİ eklenen END düğüm (node3) node2 olduğu listede endeksi 2 için geri başvuru vardır. Bu node0 (START) olduğu listede endeksi 0 bir geri başvuru vardır. Bu ters çevirin ve node0 bir kısa yolu olsun -> node2 -> node3.

Bu bir ağaç / grafik ya da bir orman mı? Bir orman ise, yol her zaman tanımlanmış olmayabilir. Bu bir ağaç / grafiktir durumda, Genişlik-First-Search kullanmayı deneyin.

Şöyle düşünün: diyelim ki, sizin mahallede sevimli civciv bulmak için gizli bir göreve çıkıyor vardır. Kendi evinde başlar ve BAŞLANGIÇ olarak işaretlemek. Sen hemen yanında, en yakın komşuları çalmak için gitmek istiyorum? Yani, biz sadece bunu yapacağız - Bir kuyrukta baştan bağlı tüm düğümleri itin. Şimdi, bu kuyruktaki tüm düğümler için komşu arama tekrarlayın. Eğer kız olsun kadar Ve, err, bunu yaparken END tutun.