Create matrix with entries unique to row and column R
up vote
2
down vote
favorite
I need to find all possible 5x5 matrix of integers 1-5 unique to each row and column (imagine a Sudoku) in R.
Is there any efficient way of doing this without creating all 120C5 matrices and then finding the fitting ones?
Thank you!
r matrix
add a comment |
up vote
2
down vote
favorite
I need to find all possible 5x5 matrix of integers 1-5 unique to each row and column (imagine a Sudoku) in R.
Is there any efficient way of doing this without creating all 120C5 matrices and then finding the fitting ones?
Thank you!
r matrix
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)
– r2evans
Nov 8 at 23:02
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
1
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
1
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
1
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I need to find all possible 5x5 matrix of integers 1-5 unique to each row and column (imagine a Sudoku) in R.
Is there any efficient way of doing this without creating all 120C5 matrices and then finding the fitting ones?
Thank you!
r matrix
I need to find all possible 5x5 matrix of integers 1-5 unique to each row and column (imagine a Sudoku) in R.
Is there any efficient way of doing this without creating all 120C5 matrices and then finding the fitting ones?
Thank you!
r matrix
r matrix
edited Nov 8 at 23:07
asked Nov 8 at 22:58
Maximilian Niroomand
184
184
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)
– r2evans
Nov 8 at 23:02
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
1
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
1
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
1
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19
add a comment |
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)
– r2evans
Nov 8 at 23:02
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
1
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
1
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
1
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)– r2evans
Nov 8 at 23:02
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)– r2evans
Nov 8 at 23:02
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
1
1
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
1
1
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
1
1
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
As I said in my comment above, matrices of this type are called Latin squares.
For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.
By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.
First we read and rearrange the data
reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56
Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.
library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)
Lastly, we go over all the reduced Latin squares and permute them in all possible ways
allLS <- sapply(reduced, function(m)
LS <- vector("list", gamma(6) * gamma(5))
for(i in 1:gamma(5))
for(j in 1:gamma(6))
LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
LS
)
Takes just a couple of seconds and we have the result
length(allLS)
# [1] 161280
It is easy to verify that they all are different
table(table(sapply(allLS, paste0, collapse = "")))
# 1
# 161280
and you could also check if they all are Latin squares.
Very impressive, Julius! Now I can turn off my back-burner. (I really likelist()[rep(...)]instead ofreplicate(n,NULL,simplify=F), too ... much faster.)
– r2evans
Nov 9 at 0:29
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:vector("list", n). Around another 5 times faster thanlist()[rep(1, n)].
– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (wheren <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stablevectorfunction ...
– r2evans
Nov 9 at 0:37
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
As I said in my comment above, matrices of this type are called Latin squares.
For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.
By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.
First we read and rearrange the data
reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56
Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.
library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)
Lastly, we go over all the reduced Latin squares and permute them in all possible ways
allLS <- sapply(reduced, function(m)
LS <- vector("list", gamma(6) * gamma(5))
for(i in 1:gamma(5))
for(j in 1:gamma(6))
LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
LS
)
Takes just a couple of seconds and we have the result
length(allLS)
# [1] 161280
It is easy to verify that they all are different
table(table(sapply(allLS, paste0, collapse = "")))
# 1
# 161280
and you could also check if they all are Latin squares.
Very impressive, Julius! Now I can turn off my back-burner. (I really likelist()[rep(...)]instead ofreplicate(n,NULL,simplify=F), too ... much faster.)
– r2evans
Nov 9 at 0:29
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:vector("list", n). Around another 5 times faster thanlist()[rep(1, n)].
– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (wheren <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stablevectorfunction ...
– r2evans
Nov 9 at 0:37
add a comment |
up vote
3
down vote
accepted
As I said in my comment above, matrices of this type are called Latin squares.
For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.
By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.
First we read and rearrange the data
reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56
Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.
library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)
Lastly, we go over all the reduced Latin squares and permute them in all possible ways
allLS <- sapply(reduced, function(m)
LS <- vector("list", gamma(6) * gamma(5))
for(i in 1:gamma(5))
for(j in 1:gamma(6))
LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
LS
)
Takes just a couple of seconds and we have the result
length(allLS)
# [1] 161280
It is easy to verify that they all are different
table(table(sapply(allLS, paste0, collapse = "")))
# 1
# 161280
and you could also check if they all are Latin squares.
Very impressive, Julius! Now I can turn off my back-burner. (I really likelist()[rep(...)]instead ofreplicate(n,NULL,simplify=F), too ... much faster.)
– r2evans
Nov 9 at 0:29
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:vector("list", n). Around another 5 times faster thanlist()[rep(1, n)].
– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (wheren <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stablevectorfunction ...
– r2evans
Nov 9 at 0:37
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
As I said in my comment above, matrices of this type are called Latin squares.
For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.
By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.
First we read and rearrange the data
reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56
Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.
library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)
Lastly, we go over all the reduced Latin squares and permute them in all possible ways
allLS <- sapply(reduced, function(m)
LS <- vector("list", gamma(6) * gamma(5))
for(i in 1:gamma(5))
for(j in 1:gamma(6))
LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
LS
)
Takes just a couple of seconds and we have the result
length(allLS)
# [1] 161280
It is easy to verify that they all are different
table(table(sapply(allLS, paste0, collapse = "")))
# 1
# 161280
and you could also check if they all are Latin squares.
As I said in my comment above, matrices of this type are called Latin squares.
For a start, we already know that there are 56 so-called reduced Latin squares and 161280 all Latin squares of size 5. The reduced Latin squares are such that both the first column and the first row are just 1, 2, 3, 4, 5 (in this order). Given those reduced Latin squares, one may easily (as long as the size is not greater than 5) generate all Latin squares: permute all the rows except the first one and permute all the columns. Hence, as expected, 161280=5!*4!*56.
By restricting the first row and column one could generate 4!*3!*2!=288 matrices and check which 56 are Latin squares. However, I'm going to skip that and take their list from here.
First we read and rearrange the data
reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56
Now let's generate all 5! and 4! permutations of 1, 2, 3, 4, 5 and 1, 2, 3, 4, respectively.
library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)
Lastly, we go over all the reduced Latin squares and permute them in all possible ways
allLS <- sapply(reduced, function(m)
LS <- vector("list", gamma(6) * gamma(5))
for(i in 1:gamma(5))
for(j in 1:gamma(6))
LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
LS
)
Takes just a couple of seconds and we have the result
length(allLS)
# [1] 161280
It is easy to verify that they all are different
table(table(sapply(allLS, paste0, collapse = "")))
# 1
# 161280
and you could also check if they all are Latin squares.
edited Nov 9 at 0:32
answered Nov 9 at 0:00
Julius Vainora
27.6k75878
27.6k75878
Very impressive, Julius! Now I can turn off my back-burner. (I really likelist()[rep(...)]instead ofreplicate(n,NULL,simplify=F), too ... much faster.)
– r2evans
Nov 9 at 0:29
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:vector("list", n). Around another 5 times faster thanlist()[rep(1, n)].
– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (wheren <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stablevectorfunction ...
– r2evans
Nov 9 at 0:37
add a comment |
Very impressive, Julius! Now I can turn off my back-burner. (I really likelist()[rep(...)]instead ofreplicate(n,NULL,simplify=F), too ... much faster.)
– r2evans
Nov 9 at 0:29
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:vector("list", n). Around another 5 times faster thanlist()[rep(1, n)].
– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (wheren <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stablevectorfunction ...
– r2evans
Nov 9 at 0:37
Very impressive, Julius! Now I can turn off my back-burner. (I really like
list()[rep(...)] instead of replicate(n,NULL,simplify=F), too ... much faster.)– r2evans
Nov 9 at 0:29
Very impressive, Julius! Now I can turn off my back-burner. (I really like
list()[rep(...)] instead of replicate(n,NULL,simplify=F), too ... much faster.)– r2evans
Nov 9 at 0:29
1
1
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:
vector("list", n). Around another 5 times faster than list()[rep(1, n)].– Julius Vainora
Nov 9 at 0:33
@r2evans, thanks! And now your comment reminded me of something even nicer and faster:
vector("list", n). Around another 5 times faster than list()[rep(1, n)].– Julius Vainora
Nov 9 at 0:33
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (where
n <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stable vector function ...– r2evans
Nov 9 at 0:37
I had already benchmarked the first two (2 OOM faster), this third is another OOM faster still (where
n <- gamma(6)*gamma(5)). I don't know why I keep forgetting the stable vector function ...– r2evans
Nov 9 at 0:37
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53217441%2fcreate-matrix-with-entries-unique-to-row-and-column-r%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
sapply(1:5, function(i) (1:5 - i) %% 5 + 1). (This was an easy one, but for future questions, please show some effort on your part. This isn't a free-code-service. If this is homework, I hope I get an "A".)– r2evans
Nov 8 at 23:02
Hi sorry I need to find all possible combinations not just one - sorry for not making that clear.
– Maximilian Niroomand
Nov 8 at 23:05
1
It's an interesting problem, and one I may put on the back burner for a while. However, it's too much for quick Q/As on SO, so you may not get a response. Or you may, who knows. But this will be more effort than most questions (that I see) typically require. Good luck.
– r2evans
Nov 8 at 23:09
1
Such matrices are called latin squares. See stackoverflow.com/a/49203589/1320535 for how to generate random ones. Generating all of them is indeed not straightforward, see en.wikipedia.org/wiki/Latin_square#Algorithms.
– Julius Vainora
Nov 8 at 23:18
1
I agree with @r2evans. This is a computationally interesting question. I strongly recommend that you yourself give this a try first. You can find resources on the net, and even here on SO. Show a code attempt at solving the problem, and I can guarantee that you will get a much better response (and you will learn a lot more as well). At the moment this reads too much like "gimme teh codez".
– Maurits Evers
Nov 8 at 23:19