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

带约束的数组B洗牌问题:同一B值对应不超3个不同A值

满足约束条件的B数组洗牌方案

问题背景

现有两个数组:

  • A:1到4的数值各重复8次,总长度32
  • B:1到8的数值各重复4次,总长度32

需要对B进行洗牌,核心约束:同一个B值对应的不同A值数量不能超过3个(即每个B值的4个实例,最多只能出现在3种不同的A值对应的位置上)。直接用random.shuffle(B)无法保证这个约束,以下是可行的实现方案。

实现思路

核心是给每个B值的4个实例定向分配到最多3个A值对应的位置集合中,避免分散到全部4个A分组。具体步骤:

  1. 把A数组的位置按A的值分组,记录每个A值对应的所有索引位置
  2. 对每个B值,随机选择1-3个A分组作为分配目标
  3. 把4个B实例随机分配到选中的A分组的空闲位置中
  4. 按索引位置填充得到最终的洗牌后B数组

代码实现

import random
from collections import defaultdict

# 构造原始数组A和B(比numpy写法更简洁直观)
A = [1]*8 + [2]*8 + [3]*8 + [4]*8
B = [num for num in range(1, 9) for _ in range(4)]

# 1. 按A的值分组,记录每个A值对应的所有索引位置
pos_by_a = {
    1: list(range(8)),
    2: list(range(8, 16)),
    3: list(range(16, 24)),
    4: list(range(24, 32))
}

# 2. 打乱每个A分组的位置顺序,保证分配的随机性
available_pos = {}
for a_val in pos_by_a:
    random.shuffle(pos_by_a[a_val])
    available_pos[a_val] = pos_by_a[a_val].copy()

# 3. 初始化洗牌后的B数组
B_shuffled = [0] * 32

# 4. 逐个处理每个B值的分配逻辑
for b_val in range(1, 9):
    # 随机选择1-3个A分组作为该B值的分配目标
    num_target_groups = random.randint(1, 3)
    selected_a_groups = random.sample(list(pos_by_a.keys()), num_target_groups)
    
    # 把4个B实例随机分配到选中的分组中(比如3+1、2+2、2+1+1等)
    allocation_counts = []
    remaining_instances = 4
    for i in range(num_target_groups - 1):
        # 保证每个分组至少分到1个,剩下的留给最后一个分组
        cnt = random.randint(1, remaining_instances - (num_target_groups - i - 1))
        allocation_counts.append(cnt)
        remaining_instances -= cnt
    allocation_counts.append(remaining_instances)
    
    # 从对应A分组的空闲位置中取位置,填充当前B值
    for a_group, cnt in zip(selected_a_groups, allocation_counts):
        for _ in range(cnt):
            pos = available_pos[a_group].pop()
            B_shuffled[pos] = b_val

# 可选:验证结果是否符合约束
print("=== 约束验证结果 ===")
b_associated_a = defaultdict(set)
for a_val, b_val in zip(A, B_shuffled):
    b_associated_a[b_val].add(a_val)
for b_val in b_associated_a:
    count = len(b_associated_a[b_val])
    print(f"B值{b_val}对应不同A值数量:{count},符合约束:{count <= 3}")

# 输出最终结果
print("\n=== 最终数组 ===")
print("A:", A)
print("B_shuffled:", B_shuffled)

方案说明

  • 完全满足约束:每个B值的实例最多分配到3个A分组,不会出现对应4个不同A值的情况
  • 随机性充足:分组选择、实例分配数量、位置选择全都是随机操作,保证洗牌的随机性
  • 逻辑清晰:步骤拆分明确,容易根据需求调整(比如修改允许的最大A分组数量)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:43:19