Start by setting up the snake partition
nproc <- 4
nfile <- 16
nrep <- ceiling(nfile / nproc / 2)
snakeseq <- rep(c(seq(1,nproc), seq(nproc,1)), nrep)[1:nfile]
Now a function to generate file sizes randomly, perform the partition, and report the total size assigned to each process.
partition <- function(random=FALSE) {
sizes <- runif(nfile, 5, 20)
if(!random) {
sizes <- sort(sizes, decreasing=TRUE)
}
sapply(seq(1,nproc), function(i) {
sum(sizes[snakeseq==i])
})
}
This function calculates the Gini index of the assignments
gini <- function(sizes) {
meansize <- mean(sizes)
n <- length(sizes)
combos <- expand.grid(sizes, sizes)
num <- sum(abs(combos[[1]] - combos[[2]]))
num / (2*n*n*meansize)
}
Now compute a bunch of them and get the distribution of Gini coefficients. Do the same for random values.
gsnake <- sapply(seq(1,250), function(i) {
gini(partition())
})
grandom <- sapply(seq(1,250), function(i) {
gini(partition(TRUE))
})
Distribution of Gini coefficients for the size partitions.
library(ggplot2)
pltdata <- data.frame(snake=gsnake, random=grandom)
ggplot(data=pltdata) +
geom_density(mapping=aes(x=snake, color='snake')) +
geom_density(mapping=aes(x=random, color='random')) +
xlab('Gini coefficient of distribution') +
ggthemes::theme_solarized_2(light=FALSE) +
ggthemes::scale_color_solarized()

cat('Random partition\n')
Random partition
mean(grandom)
[1] 0.0751094
quantile(grandom, c(0.025, 0.975))
2.5% 97.5%
0.02214389 0.14303694
cat('Snake partition\n')
Snake partition
mean(gsnake)
[1] 0.01267433
quantile(gsnake, c(0.025, 0.975))
2.5% 97.5%
0.002984605 0.027710777
LS0tCnRpdGxlOiAiU25ha2UgcGFydGl0aW9uIHBlcmZvcm1hbmNlIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpTdGFydCBieSBzZXR0aW5nIHVwIHRoZSBzbmFrZSBwYXJ0aXRpb24KCmBgYHtyIGdlbnNuYWtlfQpucHJvYyA8LSA0Cm5maWxlIDwtIDE2Cm5yZXAgPC0gY2VpbGluZyhuZmlsZSAvIG5wcm9jIC8gMikKc25ha2VzZXEgPC0gcmVwKGMoc2VxKDEsbnByb2MpLCBzZXEobnByb2MsMSkpLCBucmVwKVsxOm5maWxlXQpgYGAKCk5vdyBhIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIGZpbGUgc2l6ZXMgcmFuZG9tbHksIHBlcmZvcm0gdGhlIHBhcnRpdGlvbiwgYW5kCnJlcG9ydCB0aGUgdG90YWwgc2l6ZSBhc3NpZ25lZCB0byBlYWNoIHByb2Nlc3MuCmBgYHtyIHBhcnRpdGlvbn0KcGFydGl0aW9uIDwtIGZ1bmN0aW9uKHJhbmRvbT1GQUxTRSkgewogICAgc2l6ZXMgPC0gcnVuaWYobmZpbGUsIDUsIDIwKQogICAgaWYoIXJhbmRvbSkgewogICAgICAgIHNpemVzIDwtIHNvcnQoc2l6ZXMsIGRlY3JlYXNpbmc9VFJVRSkKICAgIH0KICAgIHNhcHBseShzZXEoMSxucHJvYyksIGZ1bmN0aW9uKGkpIHsKICAgICAgICBzdW0oc2l6ZXNbc25ha2VzZXE9PWldKQogICAgfSkKfQpgYGAKClRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyB0aGUgR2luaSBpbmRleCBvZiB0aGUgYXNzaWdubWVudHMKYGBge3IgZ2luaX0KZ2luaSA8LSBmdW5jdGlvbihzaXplcykgewogICAgbWVhbnNpemUgPC0gbWVhbihzaXplcykKICAgIG4gPC0gbGVuZ3RoKHNpemVzKQogICAgY29tYm9zIDwtIGV4cGFuZC5ncmlkKHNpemVzLCBzaXplcykKICAgIG51bSA8LSBzdW0oYWJzKGNvbWJvc1tbMV1dIC0gY29tYm9zW1syXV0pKQogICAgbnVtIC8gKDIqbipuKm1lYW5zaXplKQp9CmBgYAoKTm93IGNvbXB1dGUgYSBidW5jaCBvZiB0aGVtIGFuZCBnZXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBHaW5pIGNvZWZmaWNpZW50cy4gIERvIAp0aGUgc2FtZSBmb3IgcmFuZG9tIHZhbHVlcy4KCmBgYHtyIGNvbGxlY3RzdGF0c30KZ3NuYWtlIDwtIHNhcHBseShzZXEoMSwyNTApLCBmdW5jdGlvbihpKSB7CiAgICBnaW5pKHBhcnRpdGlvbigpKQp9KQoKZ3JhbmRvbSA8LSBzYXBwbHkoc2VxKDEsMjUwKSwgZnVuY3Rpb24oaSkgewogICAgZ2luaShwYXJ0aXRpb24oVFJVRSkpCn0pCmBgYAoKRGlzdHJpYnV0aW9uIG9mIEdpbmkgY29lZmZpY2llbnRzIGZvciB0aGUgc2l6ZSBwYXJ0aXRpb25zLgpgYGB7ciBwbG90fQpsaWJyYXJ5KGdncGxvdDIpCnBsdGRhdGEgPC0gZGF0YS5mcmFtZShzbmFrZT1nc25ha2UsIHJhbmRvbT1ncmFuZG9tKQpnZ3Bsb3QoZGF0YT1wbHRkYXRhKSArIAogICAgZ2VvbV9kZW5zaXR5KG1hcHBpbmc9YWVzKHg9c25ha2UsIGNvbG9yPSdzbmFrZScpKSArIAogICAgZ2VvbV9kZW5zaXR5KG1hcHBpbmc9YWVzKHg9cmFuZG9tLCBjb2xvcj0ncmFuZG9tJykpICsKICAgIHhsYWIoJ0dpbmkgY29lZmZpY2llbnQgb2YgZGlzdHJpYnV0aW9uJykgKwogICAgZ2d0aGVtZXM6OnRoZW1lX3NvbGFyaXplZF8yKGxpZ2h0PUZBTFNFKSArIAogICAgZ2d0aGVtZXM6OnNjYWxlX2NvbG9yX3NvbGFyaXplZCgpCmBgYAoKYGBge3Igc3RhdHN9CmNhdCgnUmFuZG9tIHBhcnRpdGlvblxuJykKbWVhbihncmFuZG9tKQpxdWFudGlsZShncmFuZG9tLCBjKDAuMDI1LCAwLjk3NSkpCgpjYXQoJ1NuYWtlIHBhcnRpdGlvblxuJykKbWVhbihnc25ha2UpCnF1YW50aWxlKGdzbmFrZSwgYygwLjAyNSwgMC45NzUpKQpgYGAK