Я думаю, что проблема может заключаться в путанице между конструктором System.String
и string
функцией.
string
функция преобразует любой объект в строку, в основном вызывая ToString()
, который для массива Char просто выводит имя типа: System.Char[]
.
С другой стороны System.String
класс имеет несколько перегруженных конструкторов, один из которых является массивом символов, поэтому он создает строку:
[| 'a'; 'b'; 'c'|] |> string |> printfn "%A" // "System.Char[]"
[| 'a'; 'b'; 'c'|].ToString() |> printfn "%A" // "System.Char[]"
[| 'a'; 'b'; 'c'|] |> String |> printfn "%A" // "abc"
6 |> string |> printfn "%A" // "6"
6 .ToString() |> printfn "%A" // "6"
6 |> String |> printfn "%A" // error: no overloads for int
"abc" |> string |> printfn "%A" // "abc"
"abc" .ToString() |> printfn "%A" // "abc"
"abc" |> String |> printfn "%A" // Strangelly enough gives error too
Поиск в ширину пересекает график и на самом деле находит все пути от стартового узла. Обычно, BFS не сохраняет все пути, как бы то ни было. Вместо этого это обновляет функцию prededecessor π для сохранения кратчайшего пути. Можно легко изменить алгоритм так, чтобы π(n)
не только хранит одного предшественника, но список возможных предшественников.
Затем все возможные пути кодируются в этой функции, и путем пересечения π рекурсивно Вы получаете все возможные комбинации пути.
Один хороший псевдокод, который использует эту нотацию, может быть найден во Введении в Алгоритмы Cormen и др. и впоследствии использовался во многих Университетских сценариях на предмете. Поиск Google “BFS псевдокодирует предшественника, π\” искореняет этот хит на Exchange Стека.
Алгоритм Dijkstra применяется больше к взвешенным путям, и он кажется, что плакат желал найти все пути, не просто самое короткое.
Для этого приложения я создал бы график (Ваше приложение кажется, что не должно было бы быть направлено), и используйте свой любимый метод поиска. Это кажется на желание всех путей, не только предположения в самом коротком, так используйте простой рекурсивный алгоритм по Вашему выбору.
Единственная проблема с этим состоит в том, если график может быть циклическим.
С соединениями:
При поиске пути от 1-> 4, у Вас мог быть цикл 1-> 2-> 3-> 1.
В этом случае затем я сохранил бы стек как пересечение узлов. Вот список с шагами для того графика и получающегося стека (извините для форматирования - никакая опция таблицы):
текущий узел (возможные следующие узлы минус, куда мы произошли из) [стек]
Если Вы хотите все пути, используйте рекурсию.
Используя список смежности, предпочтительно, создают функцию f (), который пытается заполнить текущий список посещаемых вершин. Как так:
void allPaths(vector<int> previous, int current, int destination)
{
previous.push_back(current);
if (current == destination)
//output all elements of previous, and return
for (int i = 0; i < neighbors[current].size(); i++)
allPaths(previous, neighbors[current][i], destination);
}
int main()
{
//...input
allPaths(vector<int>(), start, end);
}
Вследствие того, что вектор передается значением (и таким образом любые изменения, внесенные далее вниз в рекурсивной процедуре, не являются постоянными), все возможные комбинации перечисляются.
Можно получить немного эффективности путем передачи предыдущего вектора ссылкой (и таким образом не будучи должен скопировать вектор много раз), но необходимо будет удостовериться, что вещи получают popped_back () вручную.
Еще одна вещь: если график будет иметь циклы, то это не будет работать. (Я принимаю в этом случае, что Вы захотите найти все простые контуры, затем) Прежде, чем добавить что-то в предыдущий вектор, сначала проверка, если это уже будет там.
Если Вы хотите все кратчайшие пути, используйте предложение Konrad с этим алгоритмом.
То, что Вы пытаетесь сделать, должно по существу найти путь между двумя вершинами в (направленный?) алгоритм Dijkstra выезда графика, если Вы нуждаетесь в кратчайшем пути или пишете простую рекурсивную функцию, если Вам нужны любые пути, существуют.
Исходный код немного громоздок, и вы можете использовать вместо него collection.deque, если хотите использовать BFS, чтобы определить, существует ли путь между двумя точками на графике. Вот быстрое решение, которое я взломал:
Примечание: этот метод может продолжаться бесконечно, если между двумя узлами нет пути. Я не проверял все случаи, YMMV.
from collections import deque
# a sample graph
graph = {'A': ['B', 'C','E'],
'B': ['A','C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F','D'],
'F': ['C']}
def BFS(start, end):
""" Method to determine if a pair of vertices are connected using BFS
Args:
start, end: vertices for the traversal.
Returns:
[start, v1, v2, ... end]
"""
path = []
q = deque()
q.append(start)
while len(q):
tmp_vertex = q.popleft()
if tmp_vertex not in path:
path.append(tmp_vertex)
if tmp_vertex == end:
return path
for vertex in graph[tmp_vertex]:
if vertex not in path:
q.append(vertex)