This is the next from the previous question I asked , but adds an additional level of complexity, hence a new question.
In the example below, two groups ( 39 and 380 ). I need to assign 889 people to 39 groups of 2 to 7 people , and 380 groups of 2 to 6 people . > people.
However, there is a limit to the total number of people who may belong to certain groups of groups. In the example below, the maximum value allowed for each row is in column X6.
Using the example below. If in line 2 there were six people assigned in column X2 and 120 people assigned in column X4, then the total number of people would be 18 (6 * 3) +240 (120 * 2) = 258, so that would be good, as it would be below 324.
So, for each row, I get the value X1 * X2 + X3 * X4 (to create a column X5) that is less than or equal to X6, the sum of X2 is 39, the sum of X4 is 380 and the total amount of X5 is 889. Ideally, any solution would be like possible more random (so if you repeat, you will get a different solution, if possible) and one that will work when the values ββare different from 889, 39 and 380.
Thanks!
DF <- data.frame(matrix(0, nrow = 7, ncol = 6)) DF[,1] <- c(2:7,"Sum") DF[7,2] <- 39 DF[2:6,3] <- 2:6 DF[7,4] <- 380 DF[7,5] <- 889 DF[1:6,6] <- c(359, 324, 134, 31, 5, 2) DF[1,3:4] <- NA DF[7,3] <- NA DF[7,6] <- NA
EDIT
The wording of my problem may be unclear. Here is an example of the code that I am currently using and how it does not meet the criteria set above.
homeType=rep(c("a", "b"), times=c(39, 380)) H <- vector(mode="list", length(homeType)) for(i in seq(H)){ H[[i]]$type <- homeType[i] H[[i]]$n <- 0 } # Place people in houses up to max number of people npeople <- 889 for(i in seq(npeople)){ placed_in_house <- FALSE while(!placed_in_house){ house_num <- sample(length(H), 1) if(H[[house_num]]$type == "a"){ if(H[[house_num]]$n < 7){ H[[house_num]]$n <- H[[house_num]]$n + 1 placed_in_house <- TRUE } } if(H[[house_num]]$type == "b"){ if(H[[house_num]]$n < 6){ H[[house_num]]$n <- H[[house_num]]$n + 1 placed_in_house <- TRUE } } } } # move people around to get up to min number of people for(i in seq(H)){ while(H[[i]]$n < 2){ knock_on_door <- sample(length(H), 1) if( H[[knock_on_door]]$n > 2){ H[[i]]$n <- H[[i]]$n + 1 # house i takes 1 person H[[knock_on_door]]$n <- H[[knock_on_door]]$n - 1 # house knock_on_door loses 1 person } } } Ha <- H[which(lapply(H, function(x){x$type}) == "a")] Hb <- H[which(lapply(H, function(x){x$type}) == "b")] Ha_T <- data.frame(t(table(data.frame(matrix(unlist(Ha), nrow=length(Ha), byrow=T))))) Hb_T <- data.frame(t(table(data.frame(matrix(unlist(Hb), nrow=length(Hb), byrow=T))))) DF_1 <- data.frame(matrix(0, nrow = 7, ncol = 6)) DF_1[,1] <- c(2:7,"Sum") DF_1[7,2] <- 39 DF_1[2:6,3] <- 2:6 DF_1[7,4] <- 380 DF_1[7,5] <- 889 DF_1[1:6,6] <- c(359, 324, 134, 31, 5, 2) for(i in 1:nrow(Ha_T)){DF_1[as.numeric(as.character(Ha_T[i,1]))-1,2] <- Ha_T[i,3]} for(i in 1:nrow(Hb_T)){DF_1[as.numeric(as.character(Hb_T[i,1])),4] <- Hb_T[i,3]} DF_1$X5[1:6] <- (as.numeric(as.character(DF_1$X1[1:6]))*DF_1$X2[1:6])+(as.numeric(as.character(DF_1$X3[1:6]))*DF_1$X4[1:6]) DF_1$X7 <- DF_1$X2+DF_1$X4 DF_1[1,3:4] <- NA DF_1[7,3] <- NA DF_1[7,6] <- NA
Using this example, the problem is line 2 in DF_1. The value in column X7 (X2 + X4) is greater than the allowed number indicated in column X6. What I need is a solution in which the values ββin X7 are less than or equal to the values ββin X6, but the sum of the columns X2, X4 and X5 (X1 * X2 + X3 * X4) is 39, 380 and 889 respectively (although these numbers change depending on the data used).