gpt4 book ai didi

将值随机分配到满足多个标准的不同大小组的数据框/矩阵中

转载 作者:行者123 更新时间:2023-12-04 15:54:33 24 4
gpt4 key购买 nike

这是上一个问题 I asked 的后续,但增加了额外的复杂性,因此是一个新问题。

我有两个组(以下示例中为 39 380 )。我需要做的是分配 889 人分成39组,由之间组成2 到 7 人与380组之间 2 到 6 人们。

但是,可以属于某些组的总人数存在限制。在下面的示例中,每行允许的最大值位于 X6 列中。

使用下面的例子。如果在第 2 行,X2 列分配了 6 个人,X4 列分配了 120 个人,那么总人数将为 18(6*3)+240(120*2) = 258,这样就可以了低于 324。

所以我对每一行所追求的是 X1*X2 + X3*X4(使 X5 列)的值小于或等于 X6,其中 X2 的总和为 39,X4 的总和为 380,总和X5 的值为 889。理想情况下,任何解决方案都应尽可能随机(因此,如果重复,您将获得不同的解决方案),并且当值与 889、39 和 380 不同时,该解决方案将起作用。

谢谢!

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

编辑

我的问题的措辞可能不是最清楚。这是我当前使用的代码示例以及它如何不符合我上面设置的标准
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

使用此示例,问题是 DF_1 中的第 2 行。 X7 列 (X2+X4) 中的值大于 X6 列中显示的允许数量。我需要的是一个解决方案,其中 X7 中的值小于或等于 X6 中的值,但 X2、X4 和 X5 (X1*X2+X3*X4) 列的总和分别等于 39、380 和 889(尽管这些数字根据所使用的数据而变化)。

最佳答案

问题中对问题的原始描述是不可能满足的,因为没有值可以满足所有这些约束。

"So what I am after for each row is a value of X1*X2 + X3*X4 (to make column X5) that is less or equal to X6 with the sum of X2 being 39, the sum of X4 being 380 and the total sum of X5 being 889. "



但是,在评论中重新陈述问题后,修改后的问题描述可以解决如下。

更新:基于评论中问题澄清的解决方案

根据评论中的澄清

"I am not actually filling the number of houses completely. I am just assigning the number of children into houses. This is why 'a' is 2 to 7 and 'b' is 2 to 6, as 'a' households will also include 1 adult and 'b' households 2. For a given area I know how many 2 to 8 person households there are (419), and how many 2,3,4,5,6,7 or 8 person households exist (359,324,134,31,5,2). I also know the total number of households with either 1 (39) or 2 (380) adults, and how many children there are (889 in my example)."



基于这些更新的信息,我们可以做以下事情,其中​​我们循环 1) 计算根据标准可以分配的每种类型的房屋数量,2) 随机选择一种仍然可以分配的房屋类型而不会违反规则之一 3) 并重复直到所有 889 个 child 都在家里。请注意,我在这里使用了更具描述性的列名称,以便更容易地遵循逻辑:
DT <- data.table(HS1 = 2:7, # type 1 house size
NH1 = 0, # number of type 1 houses with children
HS2 = 1:6, # type 2 house size
NH2 = 0, # number of type 2 houses with children
C = 0, # number of children in houses
MaxNH = c(359, 324, 134, 31, 5, 2)) # maximum number of type1+type 2 houses
NR = DT[,.N]
set.seed(1234)
repeat {
while (DT[, sum(C) < 889]) {
DT[, MaxH1 := (MaxNH - NH1 - NH2)]
DT[, MaxH2 := (MaxNH - NH1 - NH2)]
DT[1,MaxH2 := 0 ]
DT[MaxH1 > 39 - sum(NH1), MaxH1 := 39 - sum(NH1)]
DT[MaxH2 > 380- sum(NH2), MaxH2 := 380- sum(NH2)]
if (DT[, sum(NH1)] >= 39) DT[, MaxH1 := 0]
if (DT[, sum(NH2)] >= 380) DT[, MaxH1 := 0]

if (DT[, all(MaxH1==0) & all(MaxH2==0)]) { # check if it is not possible to assign anyone else to a group
print("No solution found. Check constraints or try again")
break
}
# If you wish to preferentially fill a particular type of house, then change the probability weights in the next line accordingly
newgroup = sample(2*NR, 1, prob = DT[, c(MaxH1, MaxH2)])
if (newgroup > NR) DT[rep(1:NR, 2)[newgroup], NH2 := NH2+1] else DT[rep(1:NR, 2)[newgroup], NH1 := NH1+1]

DT[, C := HS1*NH1 + HS2*NH2]
}
if (DT[, sum(C)==889]) break
}

DT[,1:6, with=F]
# HS1 NH1 HS2 NH2 C MaxNH
#1: 2 7 1 0 14 359
#2: 3 7 2 218 457 324
#3: 4 14 3 76 284 134
#4: 5 9 4 14 101 31
#5: 6 2 5 3 27 5
#6: 7 0 6 1 6 2

colSums(DT[, .(NH1, NH2, C)])
# NH1 NH2 C
# 39 312 889

关于将值随机分配到满足多个标准的不同大小组的数据框/矩阵中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38975836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com