Advertisement
Guest User

Untitled

a guest
Dec 14th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.34 KB | None | 0 0
  1. class Graf
  2. {
  3. public List<Node> Nodes;
  4. public List<Krawędź> Krawędzie;
  5. public List<Node> odwiedzone;
  6. public List<Node> zwracanieWęzłów;
  7. public Dictionary<Node, Para> odległości;
  8. public List<Krawędź> ZnajdźKrawędzie(Node n)
  9. {
  10. return this.Krawędzie.Where(k => k.start == n || k.koniec == n).ToList();
  11. }
  12. public Graf(int wartość)
  13. {
  14. Krawędzie = new List<Krawędź>();
  15. Nodes = new List<Node>();
  16. }
  17. public string SPA(Node start, Node koniec)
  18. {
  19. this.odwiedzone = new List<Node>();
  20. this.zwracanieWęzłów = new List<Node>();
  21. this.odległości = new Dictionary<Node, Para>();
  22. this.AD(start);
  23. this.ZwróćKolejnoWęzły(koniec);
  24. return "Najszybsza droga między węzłami " + start + " i " + koniec + " to: " + string.Join(" ", this.zwracanieWęzłów)
  25. + " i wynosi ona " + Convert.ToInt32(odległości[koniec].odległość) + " jed.";
  26. }
  27. public void AD(Node n)
  28. {
  29. if (this.odwiedzone.Contains(n))
  30. return;
  31. if (odwiedzone.Count == 0)
  32. this.odległości.Add(n, new Para(null, 0));
  33. this.odwiedzone.Add(n);
  34. List<Krawędź> kr = this.ZnajdźKrawędzie(n);
  35. // poniższy foreach dodaje do słownika "odległości" kolejne elementy w postaci
  36. // (następny węzeł, (akutalny węzeł, najszybsza droga do tego węzła)).
  37. // Jeśli dany klucz już istnieje w słowniku to else rozpatruje czy aktualna droga nie jest szybsza,
  38. // a jeżeli jest to podmienia wartość dla tego klucza(czyli ostatni zapisany do tego klucza węzeł na aktualny węzeł
  39. // oraz ostatnią zapisaną drogę na aktualną drogę)
  40. foreach (var k in kr)
  41. {
  42. if (!this.odwiedzone.Contains(k.WeźDrugi(n)))
  43. {
  44. if (!odległości.ContainsKey(k.WeźDrugi(n)))
  45. this.odległości.Add(k.WeźDrugi(n), new Para(n, k.waga + odległości[n].odległość));
  46. else
  47. if (this.odległości[k.WeźDrugi(n)].odległość > k.waga + odległości[n].odległość)
  48. this.odległości[k.WeźDrugi(n)] = new Para(n, k.waga + odległości[n].odległość);
  49. }
  50. }
  51. // poniższy foreach wywołuje metodę AD(node n) gdzie n jest kluczem w słowniku z najmniejszą wartością drogi, który nie jest jeszcze dodany do odwiedzone
  52. // np ze słownika odległości=(2,(1-6)), (3,(1-4)), (4,(3-8)); wywoła element nr 1(czyli drugi,bo wartość jego drogi wynosi 4).
  53. // Zostaje wywołana metoda AD(3), bo kluczem elementu nr 1 jest właśnie węzeł trzeci.
  54. foreach (var k in kr)
  55. {
  56. if (!this.odwiedzone.Contains(k.WeźDrugi(n)))
  57. AD(odległości.OrderBy(x => x.Value.odległość).First(x => !this.odwiedzone.Contains(x.Key)).Key);
  58. }
  59. }
  60. public void ZwróćKolejnoWęzły(Node ostatni)
  61. {
  62. // metoda ta dostaje na początku węzeł do którego chcieliśmy się dostać
  63. // a następnie dodaje do listy zwracanieWęzłow każdy węzeł który zostanie wywołany.
  64. // Następny węzeł do wywołania to poprzednik naszego aktualnego węzła, czyli klucza w danym elemencie słownika odległości
  65. // np jezeli nasz węzeł do którego chcemy sie dostać to 4 to szukamy w słowniku elementu z kluczem 4 (np. (4,2-8)),
  66. // a następnie wywołujemy jego poprzednika czyli węzeł 2, następnie znowu szukamy elementu z kluczem 2 (np. (2,1-2)),
  67. // a ze to jest początkowy węzeł naszej drogi który nie ma poprzednika (np (1,null-0)) to zamiast zwracania poprzednika
  68. // odwracamy listę zwracanieWęzłów (inaczej lista szła by od ostatniego do pierwszego elementu drogi)
  69. zwracanieWęzłów.Add(ostatni);
  70. Node poprzednik = this.odległości[ostatni].n;
  71. if (poprzednik != null)
  72. ZwróćKolejnoWęzły(poprzednik);
  73. else
  74. zwracanieWęzłów.Reverse();
  75. }
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement