Как я могу улучшить производительность этой программы?
Здравствуйте, я написал код, который работает на графике, содержащем 36692 узла. программа должна найти все кратчайшие пути в графе. график неориентирован, невзвешен и разрежен. Я не могу использовать алгоритм Флойда-warshall-за сложности это составляет o(П^3). так, я Дейкстры и это повторять |в| время, поэтому сложность алгоритма o(ве+в^2LOGV).поскольку граф является разреженным |е|&ЛТ;&ЛТ;|в|, так Дейкстры лучше, чем Флойд-warshal АЛГ. но время работы снова длинное(более 4 часов). есть ли кто-нибудь, кто может предложить мне способ сократить время работы этой программы?
Func<Edge, double> edgeCost = e => 1; TryFunc<TVertex, IEnumerable<Edge>> tryGetPaths = null; Parallel.For(0, d.Count, i => { Parallel.For(i+1, d.Count, j => { tryGetPaths = graph.ShortestPathsDijkstra(edgeCost, i.ToString()); TVertex target = j.ToString(); IEnumerable<Edge> path; if (tryGetPaths(target, out path)) apl[i,j] = path.Count(); }); });
Что я уже пробовал:
Я использовал "parallel. for", чтобы увеличить скорость его запуска, но для этого требуется много времени.
Richard Deeming
Я бы начал с перемещения декларации о tryGetPaths
внутри первого Parallel.For
, и назначьте его на той же строке, так как он, по-видимому, не зависит ни от чего внутри внутреннего цикла:
Parallel.For(0, d.Count, i => { TryFunc<TVertex, IEnumerable<Edge>> tryGetPaths = graph.ShortestPathsDijkstra(edgeCost, i.ToString()); Parallel.For(i+1, d.Count, j => { TVertex target = j.ToString(); ... }); });
В нынешнем виде ваш код не является потокобезопасным. Каждая итерация внутреннего цикла перезаписывает общее состояние (
tryGetPaths
делегат), а затем вызывая его, не зная, изменила ли его другая итерация внешнего цикла на что-то другое.
Member 11807654
большое спасибо