Море РЕДАКТИРОВАТЬ !! Ниже
я кодирую алгоритм словарной лестницы. Пользователь вводит начальное слово, конечное слово и ха sh всех слов. Алгоритм возвращает все кратчайшие пути (несколько, если они есть) от начального слова до конечного слова. Например -> start_word = 'cold', end_word = 'warm'
output = [[cold -> cord-> card-> ward-> warm], [/ Если существует другой путь /]].
Каждое последующее слово от предыдущего отличается на один символ. Я использую поиск BFS для решения этой проблемы. Моя стратегия заключалась в том, чтобы вернуть все пути, а затем выбрать самые короткие из возвращенного списка. Это мой код для возврата всех путей:
auto word_ladder::generate(std::string const& from, std::string const& to, absl::flat_hash_set<std::string> const& lexicon) -> std::vector<std::vector<std::string>> {
absl::flat_hash_set<std::string> visited = {};
std::queue<std::vector<std::string>> search_queue = {};
std::vector<std::vector<std::string>> paths = {};
search_queue.push(std::vector<std::string>{from});
while (!search_queue.empty()) {
auto word = search_queue.front();
search_queue.pop();
auto neighbours = generate_neighbours(word.back(), lexicon);
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
continue;
}
if (visited.find(i) != visited.end()) {
continue;
}
search_queue.push(new_word);
visited.insert(i);
}
}
return paths;
}
Он действительно возвращает несколько путей, однако проблема в том, что он не возвращает все пути. Один из путей, который он возвращает ->
1) бодрствовать, осознавать, клясться, делиться, шир, ширр, шиер, чистый, овца, сон
однако путь не возвращается -> 2) «бодрствовать», «осознавать», «клясться», «делиться», «шарн», «шон», «показывать», «блеск», «овец», «спать»
I Я почти уверен, что причина в том, что, как я его закодировал, слово «share» помечается как посещенное при первой встрече (в 1)). Следовательно, он не go по второму пути (в 2))
Чтобы решить эту проблему, я немного изменил свое значение на l oop:
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
continue;
}
for (auto &j: word) {
if (j == i) {
continue;
}
}
search_queue.push(new_word);
}
Идея была чтобы проверить, посещалось ли слово в пути, который вы отслеживаете в очереди, а не глобально. Однако это решение по какой-то причине застревает где-то в al oop и не завершается (я предполагаю, что из-за большого набора данных?).
Что-то не так с моим кодом во втором или требуется слишком долго из-за большого набора данных? Как я могу лучше найти решение?
EDIT !!!
Теперь я вместо того, чтобы искать все пути, нахожу длину кратчайшего пути, а затем выполняю BFS до этой глубины, чтобы получить все пути на этой глубине.
auto word_ladder::generate(std::string const& from, std::string const& to, absl::flat_hash_set<std::string> const& lexicon) -> std::vector<std::vector<std::string>> {
absl::flat_hash_set<std::string> visited = {};
visited.insert(from);
std::queue<std::vector<std::string>> search_queue = {};
std::vector<std::vector<std::string>> paths = {};
search_queue.push(std::vector<std::string>{from});
auto length = find_shortest_path_length(from, to, lexicon);
std::cout << "length is: " << length << "\n";
// auto level = 0;
std::unordered_map<std::string, int> level_track = {};
level_track[from] = 0;
while (!search_queue.empty() ) {
auto word = search_queue.front();
search_queue.pop();
// **
if (level_track[word.back()] <= length) {
auto neighbours = generate_neighbours(word.back(), lexicon);
const auto &parent = word.back();
for (auto &i: neighbours) {
auto new_word = word;
new_word.push_back(i);
if (i == to) {
paths.push_back(new_word);
std::cout << "The level at the path was " << level_track[parent] << "\n";
continue;
}
if (path_crossed(word, i)) {
continue;
}
search_queue.push(new_word);
level_track[i] = level_track[parent] + 1;
}
}
}
return paths;
}
Решение теперь прекращается, поэтому определенно проблема ранее заключалась в большом количестве поисков. Однако мой алгоритм все еще не дает мне правильного ответа, так как то, как я отслеживаю глубину моих узлов (слов), почему-то неверно.