В конечном счете, любой алгоритм должен будет вызывать vertices_adjacent
для каждой отдельной пары вершин, которые оказываются принадлежащими отдельным компонентам, потому что в противном случае он никогда не сможет проверить отсутствие связи между этими компонентами.
Теперь, если большинство вершин принадлежат одному компоненту, таких пар может быть не слишком много;но если вы не ожидаете , то большинство вершин принадлежат одному компоненту, нет особого смысла оптимизировать именно для этого случая.Итак, отбрасывая этот случай, самый лучший сценарий выглядит так:
- Оказывается, что это ровно два компонента, каждый с одинаковым количеством вершин (½ | V |каждый).Таким образом, существует ¼ | V | 2 пар вершин, которые принадлежат отдельным компонентам, и вам необходимо вызвать
vertices_adjacent
для каждой из этих пар. - Этидва компонента оказываются законченными, или вам чрезвычайно повезло в выборе ребер для проверки в первую очередь, так что вы можете обнаружить подключенные детали, проверив просто | V |- 2 пары.
.,,который все еще включает создание making | V | 2 + | V |- 2 звонка на vertices_adjacent
.Для сравнения, подход списка построения смежности составляет ½ | V | 2 - ½ | V |вызовов - это больше, чем в лучшем случае, но с коэффициентом меньше 2. (И сценарий худший случай просто эквивалентен подходу со списком сборки-смежности.происходит, если ни один из компонентов не содержит более двух вершин, или если граф является ациклическим, и вы вряд ли выберете ребра для проверки в первую очередь. Большинство графов будет где-то посередине.)
Так что это, вероятно, не стоитпытаясь оптимизировать слишком близко для точного минимального количества вызовов до vertices_adjacent
.
Тем не менее, ваш подход кажется мне довольно разумным;он не делает никаких вызовов на vertices_adjacent
, которые явно не нужны, поэтому единственное улучшение было бы вероятностным, если бы он мог лучше угадать, какие вызовы окажутся полезными для устранения более поздних вызовов.
Одна возможность: во многих графах есть некоторые вершины, которые имеют много соседей, и некоторые вершины, которые имеют относительно немного, согласно степенному распределению .Поэтому, если вы расставите приоритеты по вершинам, основываясь на том, сколько соседей у них уже есть, вы можете воспользоваться этим шаблоном.(Я думаю, что это особенно вероятно, будет полезно, если большинство вершин действительно do принадлежат одному компоненту, что является единственным случаем, когда улучшение «лучше, чем фактор 2» возможно даже.) Но вам придется проверить, действительно ли это имеет значение для графиков, которые вас интересуют.