Предположим, у меня есть граф с 5 узлами. Каждый узел имеет определенное количество ребер (без ребер от узла к себе), которые называются степенью этого узла. Я хочу создать новый набор ребер, чтобы каждый узел имел ту же степень, что и раньше.
Моя первая попытка - создать вектор, в котором каждый узел v имеет записи степени (v), выбрать этот вектор (чтобы получить перестановку этого вектора), разделить этот вектор на два вектора равной длины и проверить если n-я запись в двух векторах отличается (назовите это условие 1 ). Если это так, два вектора сформировали бы список ребер без ребер от узла к себе.
Для 5 узлов это будет работать нормально, но для 1000+ узлов и некоторых узлов со степенью (превышающей 100) требуется многократное повторение, пока условие 1 не будет выполнено.
Моя вторая попытка была sample()
, создать два вектора и снова произвести выборку из тех пар узлов, которые не удовлетворяли условие 1 , затем добавить разделить результат и добавить их к оставшимся двум векторам. и повторить, что пару раз, пока либо условие 1 не будет выполнено, либо набор узлов, нарушающих условие 1 , не может быть надлежащим образом сопоставлен для формирования правильных ребер (то есть тех, которые не нарушают условие 1 ).
Явное вычисление всех возможных векторов (меток узлов), удаление неправильного и затем случайный выбор одного не очень хорошая идея для больших графов. Это заняло бы слишком много памяти, и простое вычисление их всех, вероятно, также заняло бы много времени.
Что я ищу
Учитывая вектор узлов (только целочисленные метки, четную длину), вернуть случайно выбранный (так что потребуется использовать что-то вроде sample()
или некоторую другую функцию, основанную на псевдослучайных числах) набор пар узлов (предпочтительно как два вектора, которые формируют список ребер), так что каждое ребро соединяет два разных узла, а степени узлов остаются неизменными.
Пример кодирования
Небольшой пример кодирования с использованием 5 узлов:
E<-c(1,1,1,1,2,2,2,3,3,4,4,4,5,5)
Допустимое решение:
V1<-c(1,1,1,1,2,2,4)
V2<-c(2,3,4,5,3,4,5)
Другое правильное решение (с повторяющимся ребром, которое разрешено):
V1<-c(1,1,1,1,2,2,3)
V2<-c(2,3,4,5,4,4,5)
Недопустимое решение (у него есть самообладание, что недопустимо):
V1<-c(1,2,1,1,2,2,4)
V2<-c(1,3,4,5,3,4,5)
Использование (экзотических) библиотек R - это хорошо, они особенно приветствуются, если им удается ускорить процесс.
Дополнительная информация
Вместо того, чтобы просто иметь вектор узлов (с повторениями столько раз, сколько они появляются в ребрах), можно предположить, что фактические ребра в исходном графе также предоставляются.