Création de matrices aléatoires

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Matthieu Reichstadt
Messages : 1
Enregistré le : 08 Déc 2017, 13:48

Création de matrices aléatoires

Messagepar Matthieu Reichstadt » 08 Déc 2017, 15:05

Bonjour,
j'ai une question pour moi insoluble.
J'ai une matrice disons de 100x100 remplie de 0 et 1.
Pour chacune des lignes et des colonnes j'ai un nombre connu de 0 et 1.
Je souhaiterais créer n matrices random ayant pour chaque ligne et chaque colonne le même nombre de 0 et 1 que ma matrice d'origine, mais à des emplacements aléatoires.

J'avoue m'arracher les cheveux là-dessus. Est-ce que quelqu'un saurait comment il est possible de mettre ça en place?

Merci beaucoup au(x) génie(s) qui arriveront à m'aider...

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Création de matrices aléatoires

Messagepar Logez Maxime » 08 Déc 2017, 15:18

Bonjour,

voilà un code trouver une fois sur le net (mais je ne sais plus où) :

Code : Tout sélectionner

ronetab <- function(m1,m2,debug=F)
{
  ## Purpose: sample from a table with fixed margins and {0,1} cell values
  ## ----------------------------------------------------------------------
  ## Arguments: m1, m2 - two margins
  ## ----------------------------------------------------------------------
  ## Author: Charles C. Berry, Date: 28 Apr 2007, 08:21
  ## GPL 2.0 or better
 
  stopifnot( sum(m1)==sum(m2)|| max(m1)>length(m2) || max(m2)>length(m1) )
 
  i.list <- j.list <- list()
  k <- 0
  while( sum(m1)>0 ){
    k <- k+1
    if ( sum(m1!=0) > sum(m2!=0) ){
      i <- which.max( m1)
      j <- msample( m1[i], m2 )
      i.list[[ k ]] <- rep( i, m1[i] )
      j.list[[ k ]] <- j
      m1[i] <- 0
      m2[ j ] <- m2[ j ] - 1
    } else {
      j <- which.max( m2 )
      i <- msample( m2[j], m1 )
      i.list[[ k ]] <- i
      j.list[[ k ]] <- rep( j, m2[j] )
      m2[j] <- 0
      m1[ i ] <- m1[ i ] - 1
    }
  }
  res <- array(0, c(length(m1), length(m2) ) )
  res[ cbind( unlist(i.list), unlist(j.list) ) ] <- 1
  res
}

msample <- function(x,marg){
  ## Purpose: sample at most one each from each cell of a margin
  ## ----------------------------------------------------------------------
  ## Arguments: x - number to sample, marg - a vector of integers
  ## ----------------------------------------------------------------------
  ## Author: Charles C. Berry, Date: 28 Apr 2007, 08:17
  ## GPL 2.0 or better
 
  if (!(x<=sum(marg) && all(marg>=0))) browser()
  wm <- which(marg!=0)
  if (length(wm)==1) {
    wm
  } else {
    sample( seq(along=marg), x, prob=marg )
  }
}

ronetab(c(2, 2, 2), c(2,2,2))
     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    1    0    1
[3,]    1    1    0
Cordialement,
Maxime

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Re: Création de matrices aléatoires

Messagepar François Bonnot » 11 Déc 2017, 11:04

Bonjour,
La fonction suivante donne une permutation de la matrice d'origine qui satisfait les conditions des marges :

Code : Tout sélectionner

random.mat <- function(m) {
    nr <- nrow(m)
    nc <- ncol(m)
    sr <- rowSums(m)
    sc <- colSums(m)
    m[,] <- 0
    for (i in 1:nr) {
        m[i,sc==nr-i+1] <- 1
        prob=1-(sc==nr-i+1 | sc==0)
        if (sum(prob)>0) m[i,sample(1:nc,sr[i]-sum(m[i,]),prob=prob)] <- 1
        sc <- sc-m[i,]
    }
    m
}

Exemple :

Code : Tout sélectionner

m <- matrix(0,nrow=4,ncol=5)
m[sample(1:20,10)] <- 1
m
random.mat(m)

Cependant je suppose que par "emplacements aléatoires" vous sous-entendez que les matrices générées doivent être équiprobables (parmi l'ensemble des matrices répondant à la condition). Or je ne peux pas garantir que ce soit le cas de la fonction random.mat.
Néanmoins on peut vérifier simplement dans le cas particulier d une matrice carrée dont toutes les marges valent 1 que la distribution des matrices générées a l'apparence d'une distribution uniforme (en codant une matrice par les positions du '1' dans chaque ligne, par exemple diag(4) codée par "1234")

Code : Tout sélectionner

key <- function(m) paste(apply(m,1,function(x) which(x==1)),collapse='')
random.key <- function(m) key(random.mat(m))
z <- sapply(1:24000,function(i) random.key(diag(4)))
table(z)

Ce n est évidemment pas une preuve, c est seulement une présomption d équiprobabilité.
François


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

cron