【问题标题】:Packing customers into buckets把顾客装进桶里
【发布时间】:2017-03-24 20:32:33
【问题描述】:

我说有 25 位客户。每个客户都有我们系统的多个用户,例如客户 1 有 45 个用户,客户 2 有 46 个用户……客户 25 有 1000 个用户。

我想将每个客户放入一个存储桶中,每个存储桶包含大致相等数量的用户。我知道我总共想要 5 个桶。

(这里的桶代表服务器,我想将我的客户端分配到每个服务器的用户总数大致相等的不同服务器,以防止服务器过载。1个客户端必须在同一台服务器上(即不能将 1 个客户端拆分到 2 个服务器上)。

知道将客户分配到存储桶的合适方法吗?我认为一些聚类方法可能有效(我尝试使用 R 的 kmeans),但我似乎无法找到规定每个集群中的用户总数大致相同的方法。

这是我的 R 代码,作为我迄今为止所做的示例:

#Create dataset
r <- data.frame(users=c(1000, 960, 920, 870, 850, 700, 600, 550, 520, 500, 420, 400, 390, 300, 210, 200, 160, 80, 70, 50, 49, 48, 47, 46, 45))
#Try kmeans clustering
fit <- kmeans(r, 5) 
#get cluster means
aggregate(r, by=list(fit$cluster),FUN = mean)
#append cluster assignment
r <- data.frame(r,fit$cluster)

#Plot cluster
library(cluster)
clusplot(r, fit$cluster, color=TRUE, shade=TRUE, labels=2, lines=0)
library(fpc)
plotcluster(r, fit$cluster)

这会将我的客户聚集到存储桶中,但每个存储桶中的用户数量并不大致相等。

我已将此标记为 R 问题,但如果其他包中有简单的解决方案,我会全力以赴 :-)

【问题讨论】:

    标签: r statistics k-means bin-packing


    【解决方案1】:

    我不知道这种“恒定总和采样”的推荐解决方案是什么。这是我的尝试——对项目进行排序,转换为每列代表一个样本的矩阵,每隔一行反转一次。

    代码如下:

    set.seed(1024)
    r <- data.frame(users=c(1000, 960, 920, 870, 850, 700, 600, 550, 520, 500, 420, 400, 390, 300, 210, 200, 160, 80, 70, 50, 49, 48, 47, 46, 45))
    
    a<-   r$users #runif(n = 25, 100,400) #rnorm(25,100,100) # 1:25
    #hist(a)
    df<- data.frame(id=1:25,x=a)
    
    # sort 
    x<- df$id[order(df$x)]
    # convert to matrix
    #each column of this matrix represetns one sample
    xm<-matrix(x,ncol=5,byrow = T); xm
    oldsum<-apply(matrix(df$x,ncol=5,byrow = T), 2,sum)
    
    #flip alternate rows of this sorted matrix
    i= 1:nrow(xm)
    im=i[c(F,T)]
    xm[im,]
    xm[im,]<- rev(xm[im,])
    
    # new matrix of indeices 
    xm
    
    #hence the new matrix of values
    xm2<- matrix(a[c(xm)],ncol = 5, byrow = F)
    xm
    xm2
    
    newsum<- (apply(xm2, 2,sum))
    
    # improvement
    rbind(oldsum,newsum)
    barplot(rbind(oldsum,newsum)[1,])
    barplot(rbind(oldsum,newsum)[2,])
    
    # each column of following matrix represents one sample 
    #(values are indices in original vector a)
    xm 
    

    【讨论】:

    • 我认为这样就可以了!我向你致敬。非常感谢您的努力:-)
    • 很高兴知道它有帮助。感谢您的评论。
    【解决方案2】:

    而不是尝试聚类(它解决了一个非常不同的问题,即将相似值放入聚类中),您在这里有一个bin packing problem 的经典变体。

    这些往往是 NP 难的,因此找到最佳解决方案非常昂贵。相反,尝试一种贪婪策略:将最小桶大小估计为总/桶。以递减的大小处理元素,并始终将它们放入可用空间最多的存储桶中。为了获得更好的结果,添加一个优化函数,如果这样可以改善结果,则在成对的桶之间交换元素。如果你有很多小的值,这样的策略可能会很有效。

    【讨论】:

    • 是的,这看起来像是一个装箱问题,好吧!感谢您的回复。下面@R.S 的回复看起来会奏效!很高兴:-)
    猜你喜欢
    • 2015-01-23
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2016-09-20
    • 1970-01-01
    • 2019-06-04
    相关资源
    最近更新 更多