You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将内容ID数组按递减数量分配给用户ID数组?

基于幂律分布的内容ID分配方案

核心思路

要实现「首位用户分配最多、多数末尾用户分配0个」的需求,**幂律分布(如Zipf定律)**是最匹配的数学模型——它天然符合「少数个体占据大量资源,多数个体资源极少甚至为0」的长尾特征,完全适配你的需求。

具体实现步骤

1. 确定分配规则与参数

我们采用指数衰减模型(计算简单,长尾效果接近Zipf定律):

  • 给每个用户按索引(从0开始,对应第一个用户)计算权重:weight(i) = e^(-k * i / totalUsers),其中k为衰减系数,值越大,内容向头部用户集中的速度越快,更多末尾用户会分配到0个内容。
  • 先计算所有用户的权重总和,归一化后得到每个用户的分配比例,乘以总内容数100000得到初始分配数量。
  • 设置最小阈值(如0.5),分配数量低于阈值的用户直接设为0,确保多数末尾用户无内容。

2. 代码实现

function distribute(userIds, contentIds) {
  const totalUsers = userIds.length; // 10000
  const totalContents = contentIds.length; // 100000
  const decayCoeff = 0.0012; // 调整此值控制衰减速度,越大衰减越快
  const minThreshold = 0.5; // 低于该值的分配数直接设为0

  // 计算每个用户的权重与总权重
  const weights = [];
  let totalWeight = 0;
  for (let i = 0; i < totalUsers; i++) {
    const weight = Math.exp(-decayCoeff * i);
    weights.push(weight);
    totalWeight += weight;
  }

  // 计算初始分配数,同时截断低分配用户
  const allocations = [];
  let allocatedTotal = 0;
  for (let i = 0; i < totalUsers; i++) {
    const count = (weights[i] / totalWeight) * totalContents;
    const finalCount = count >= minThreshold ? Math.floor(count) : 0;
    allocations.push(finalCount);
    allocatedTotal += finalCount;
  }

  // 修正分配误差:将剩余内容补到头部用户,确保总数为100000
  let remaining = totalContents - allocatedTotal;
  let idx = 0;
  while (remaining > 0 && idx < totalUsers) {
    if (allocations[idx] > 0) {
      allocations[idx]++;
      remaining--;
    }
    idx++;
  }

  // 按分配数分发内容ID
  const result = {};
  let contentPointer = 0;
  for (let i = 0; i < totalUsers; i++) {
    const userId = userIds[i];
    const count = allocations[i];
    result[userId] = count === 0 
      ? [] 
      : contentIds.slice(contentPointer, contentPointer + count);
    contentPointer += count;
  }

  return result;
}

// 测试示例
const userIds = Array.from({length: 10000}, (_, i) => `user_${i}`);
const contentIds = Array.from({length: 100000}, (_, i) => `content_${i}`);
const distributionResult = distribute(userIds, contentIds);

// 验证结果
console.log('首位用户内容数:', distributionResult.user_0.length);
console.log('末尾用户内容数:', distributionResult.user_9999.length); // 输出0

3. 参数调整说明

  • decayCoeff:控制内容向头部集中的速度,比如调到0.0015时,前1000个用户即可分配完绝大多数内容,剩余9000个用户均为0;调到0.0008时,会有更多用户分到少量内容。
  • 若想要更极端的头部集中效果,可改用Zipf分布,将权重公式改为weight(i) = 1 / Math.pow(i + 1, 1.5)(指数1.5可按需调整),后续计算逻辑不变。

替代方案:线性递减+截断

如果偏好更直观的规则,可采用线性递减模型:

  • 指定前M个用户按线性递减分配(从maxCount降到1),剩余10000-M个用户分配0。
  • 通过公式M*(maxCount + 1)/2 = 100000计算参数,比如M≈447时,maxCount≈447,总和刚好接近100000,剩余9553个用户均为0。但这种方式的长尾效果不如幂律自然。

内容的提问来源于stack exchange,提问作者mesqueeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:01:28