Реализация алгоритма поиска кратчайшего пути в ширину на JS
const graph = {
you: ['alice', 'bob', 'claire'],
bob: ['anuj', 'peggy'],
alice: ['peggy'],
claire: ['thom']
anuj: [],
peggy: [],
thom: [],
johny: [],
}
//push shift
const isSeller = name => name === 'thom';
const addDeque = (friends, deque) => {
for (i=0; i<friends.length; i+=1) {
deque.push(friends[i])
}
}
const search = (name) => {
const visited = [];
const deque = []
addDeque(graph['you'], deque);
while (deque.length>0) {
const person = deque[0];
deque.shift();
if (!visited.includes(person)) {
visited.push(person)
if (isSeller(person)){
console.log(person)
return true
}
addDeque(graph[person], deque);
}
}
return false;
}
имею такую реализацию(случай с ориентированным графом), которая позволяет находить искомый ближайший элемент, так-же её легко преобразовать для нахождения длины кратчайшего пути, но никак не могу понять как сохранить кратчайший путь. интересно было бы увидеть решения для ориентированного и неориентированного графа.
Ответы (1 шт):
Автор решения: Uzakov Nikita
→ Ссылка
Удалось написать костыль(с помощью лекции: https://www.youtube.com/watch?v=S-hjsamsK8U&list=RDsBJ7ana1fgI&index=2), который работает, возможно будет кому-то полезно:
const graph = {
you: ['alice', 'bob', 'claire'],
claire: ['thom', 'johny'],
bob: ['anuj', 'peggy'],
alice: ['peggy'],
anuj: [],
peggy: [],
thom: [],
johny: []
}
const aa = (end_vertex) => {
const startPoint = 'you'; // начальная точка графа(исток)
const parents = {}; // объект с родителями, используется для построения кратчайшего пути
const distances = { // объект с дистанцией, используется для определения дублирования захода в точку и расчета длины пути, по необходимости
[startPoint]: 0 //нулеввая длина от начальной точки до неё самой
};
const queue = [startPoint]; // очередь для работы алгоритма, в нее складываем все элементы и извлекаем из неё
while (queue.length>0) { // пока очередь имеет хоть один элемент цикл будет повторяться
const currentFromQueue = queue[0]; //извлекаем первый элемент из очереди, на первой итерации он будет 'you'
queue.shift(); //удаляем первый элемент сверху очереди
for (let iter of graph[currentFromQueue]) { // для всех потомков рассматриваемого элемета
if (!distances[iter]) { // если дистанция нулевая(в точку еще не заходили)
distances[iter] = distances[currentFromQueue]+1; // добавляем длину дистанции для рассматриваемого потомка
queue.push(iter) // добавляем потомка в очередь
parents[iter] = currentFromQueue; // добавляем в массив родителей информацию о том, что текущий потомок наследуется от рассматриваемого родителя
}
}
}
const path = [end_vertex]; // начало пути с конца
let parent = parents[end_vertex]; // берем первого родителя потомка
while (!!parent) { // пока родители существуют
path.push(parent); //добавляем родителя в путь
parent = parents[parent] // ищем родителя у текущего родителя
}
path.reverse() // реверсируем путь
console.log(path)
}
aa('peggy')