Построить матрицу в зависимости от двух случайных блужданий на графе

я работаю над проектом, и я достиг этого момента, но на самом деле я застрял на нем, так как неделю назад я пробовал много идей, но все попытки кодировать мой алгоритм потерпели неудачу.

предположим, что у нас есть следующий простой график: enter image description here

края в порядке: 1--3, 1--4, 3--2

для каждого ребра определяется случайное блуждание по каждой вершине, чтобы перейти к одному из ее соседей, таких как:

для первого ребра, v1=1 ,v2=3, n1=3,4 и n2=1,2 в порядке, поэтому возможные ходы от v1 и v2:

1 to 3,3 to 1
1 to 4,3 to 1
1 to 3,3 to 2
1 to 4,3 to 2

для второго края, v1=1 ,v2=4, n1=3,4 и n2=1 в порядке, поэтому возможные ходы от v1 и v2:

1 to 3,4 to 1
1 to 4,3 to 1

для третьего края,v1=3 ,v2=2, n1=1,2 и n2=3 в порядке, поэтому возможные ходы от v1 и v2:

3 to 1,2 to 3
3 to 2,2 to 3

для всего графика есть только 8 возможных ходов у меня есть 8 переменных для построения ограничений матрица

обозначим х (в соответствии с порядком их появления); i.e

(1 to 3,3 to 1) to be represented by x_1
(1 to 4,3 to 1) to be represented by x_2
                 :
(3 to 1,2 to 3) to be represented by x_7
(3 to 2,2 to 3) to be represented by x_8

я хочу построить требуемую матрицу ограничений в зависимости от этих ходов, количество ограничений будет равно sum{i} ( number of neighbors for v1(i) * number of neighbors for v2(i) ) что составляет 10 на нашем графике.

мой алгоритм построения этой матрицы:

Step1: 1) select 1st edge, fix v1, v2, n2
       2) change n1 and fill the 1st row of the matrix by 1's in the place of the resulted moves and 0 if there is no similar move on the graph until you finish all elements in n1. 
Step2: move to the 2nd row of the matrix and select the 2nd element of n2 and
       1) loop over n1 
       2) fill the 2nd row by 1's in the place of the resulted moves until you finish all elements in n1. 
Step3: since you selected all elements in n1 and n2 for the vertices in the first edge move to a new row in the matrix 
Step4: Select next edges and do the same work done before until you finish all edges. 
Step5: select the 1st edge again and do the same work but while fixing v1,v2 &n1, loop over n2

результирующая матрица в соответствии с этим алгоритмом будет:

1 1 0 0 0 0 0 0
0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1

Что Я не удалось сделать это: как сообщить матрице, что есть ход и заменить его на 1 в его положении, и если нет движения, чтобы заменить его на 0 в его положении

мой код:

library(igraph)
graph<-matrix(c(1,3,1,4,3,2),ncol=2,byrow=TRUE)
g<-graph.data.frame(d = graph, directed = FALSE)

countercol<-0
for (edge in 1:length(E(g))){
v1<-ends(graph = g, es = edge)[1]
v2<-ends(graph = g, es = edge)[2]

n1<-neighbors(g,v1,mode=c("all"))
n2<-neighbors(g,v2,mode=c("all"))

countercol=countercol+(length(n1)*length(n2))
}

counterrow<-0
for (edge in 1:length(E(g))){
v1<-ends(graph = g, es = edge)[1]
v2<-ends(graph = g, es = edge)[2]

n1<-neighbors(g,v1,mode=c("all"))
n2<-neighbors(g,v2,mode=c("all"))

counterrow=counterrow+(length(n1)+length(n2))
}    

for (edge in 1:length(E(df))){
v1<-ends(graph = df, es = edge)[1]
v2<-ends(graph = df, es = edge)[2]
n1<-neighbors(df,v1,mode=c("all"))
n2<-neighbors(df,v2,mode=c("all"))
  ...
  ...
  ...
  }

я не ищу кого-то, чтобы написать код, то, что я хочу, это идея, чтобы программа различала возможные ходы и хранить 1 и 0 в подходящей позиции для полученного хода.

большое спасибо за любой вид помощи

1 ответов


вот решение, состоящее из двух частей

edgeMoves <- function(e) {
  umoves <- sapply(ends(graph = g, es = e), neighbors, graph = g, mode = "all", simplify = FALSE)
  do.call(paste, c(expand.grid(mapply(function(x, y) 
    paste(x, names(y), sep =" to "), ends(graph = g, es = e), umoves, SIMPLIFY = FALSE)), sep = ", "))
}
edgeConstraints <- function(e) {
  v <- ends(graph = g, es = e)
  n1 <- names(neighbors(g, v[1], mode = "all"))
  n2 <- names(neighbors(g, v[2], mode = "all"))
  t(cbind(sapply(n2, function(nn2) moves %in% paste0(v[1], " to ", n1, ", ", v[2], " to ", nn2)),
          sapply(n1, function(nn1) moves %in% paste0(v[1], " to ", nn1, ", ", v[2], " to ", n2))))
}
moves <- do.call(c, sapply(E(g), edgeMoves))
moves
# [1] "1 to 3, 3 to 1" "1 to 4, 3 to 1" "1 to 3, 3 to 2"
# [4] "1 to 4, 3 to 2" "1 to 3, 4 to 1" "1 to 4, 4 to 1"
# [7] "3 to 1, 2 to 3" "3 to 2, 2 to 3"

do.call(rbind, sapply(E(g), edgeConstraints)) * 1
#   [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# 1    1    1    0    0    0    0    0    0
# 2    0    0    1    1    0    0    0    0
# 3    1    0    1    0    0    0    0    0
# 4    0    1    0    1    0    0    0    0
# 1    0    0    0    0    1    1    0    0
# 3    0    0    0    0    1    0    0    0
# 4    0    0    0    0    0    1    0    0
# 3    0    0    0    0    0    0    1    1
# 1    0    0    0    0    0    0    1    0
# 2    0    0    0    0    0    0    0    1

порядок строк разное, но я подозреваю, что это не проблема. Кроме того, для одного края вы можете использовать edgeMoves(e) и edgeConstraints(e) * 1.