与约束的组合会找到从低到高的重新分区

2024-10-02 12:35:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个项目,我需要找到一个可以解决以下问题的算法:

有三个项目列表:

A = [1,2,3,4,5]
B = [1,2,3,4,5]
C = [1,2,3,4,5]

使用python,我可以通过以下代码行找到所有独特的组合:

allCombinations = list(set(product(A,B,C)))

但是现在我需要从所有这些组合中得到,这些组合遵循一个非常线性的重新划分

例如,有125个独特的组合,现在我想要50个组合,其中A1 B1 C1显示小于A2 B2 C2。。。(如果它几乎可以是线性的,它将是完美的)

我不知道如何解决这类问题,如何选择符合我想法的最佳组合

我可以用125种组合轻松完成,但更多的组合太难了

谢谢

#编辑

我将在这里重做这个例子

A=[1,2] 
B=[1,2] 
C=[1,2] 

此列表中的组合为

(1,1,1) (1,2,1) (1,2,2) (1,1,2) (2,1,1) (2,1,2) (2,2,1) (2,2,2)

如果我需要选择3个组合,我会选择(2,2,2)(1,2,2)(2,2,1),因为我想让A,B,C列表中的1小于A,B,C中的2

目标是生产稀有品,A、B、C代表三个项目列表。使三个列表中的第一项比第二项更加罕见

我想为很多项目做这件事


Tags: 项目代码算法a2列表a1线性product
1条回答
网友
1楼 · 发布于 2024-10-02 12:35:05

我认为你的问题有点不够明确,所以你可以选择如何准确地加权你的组合

一种可能性是选择随机组合,但组合[A[i],B[j],C[k]]的权重为i*j*k。因此,例如,组合[A2,B2,C2]被选为组合[A1,B1,C1]的可能性要高出8倍

我们可以使用random.sample进行加权采样:https://docs.python.org/3/library/random.html#random.sample

Python 3.9:

import itertools  # product
import random     # sample

def sampleCombinations(A, B, C, k):
  allCombinations = list(itertools.product(enumerate(A), enumerate(B), enumerate(C)))
  weights = [(i+1) * (j+1) * (k+1) for (i,_), (j,_), (k,_) in allCombinations]
  sampled = random.sample(allCombinations, k, counts=weights)
  sampled_clean = [(x,y,z) for (_,x), (_,y), (_,z) in sampled]
  return sampled_clean

print(sampleCombinations(['A1','A2','A3','A4','A5'], ['B1','B2','B3','B4','B5'], ['C1','C2','C3','C4','C5'], 50))

print(sampleCombinations([1, 2], [1, 2], [1, 2], 3))

注意使用enumerate来获得计算权重所需的索引i,j,k。然后,在返回组合之前,不要忘记删除sampled_clean中的索引。还请注意,权重计算为(i+1)*(j+1)*(k+1),而不是i*j*k,因为所有内容都是0索引的,而不是1索引的

注意:random.sample的“counts”关键字参数在python 3.9中是新的。在版本3.9之前,需要手动复制总体中的元素以模拟权重

Python<;3.9:

import itertools  # product
import random     # sample

def sampleCombinations(A, B, C, k):
  allCombinations = list(itertools.product(enumerate(A), enumerate(B), enumerate(C)))
  weights = [(i+1) * (j+1) * (k+1) for (i,_), (j,_), (k,_) in allCombinations]
  weightedCombinations = [c for c,w in zip(allCombinations, weights) for _ in range(w)]
  sampled = random.sample(weightedCombinations, k)
  sampled_clean = [(x,y,z) for (_,x), (_,y), (_,z) in sampled]
  return sampled_clean

print(sampleCombinations(['A1','A2','A3','A4','A5'], ['B1','B2','B3','B4','B5'], ['C1','C2','C3','C4','C5'], 50))
# [('A3', 'B4', 'C2'), ('A4', 'B4', 'C5'), ('A2', 'B5', 'C5'), ('A4', 'B4', 'C4'), ('A3', 'B1', 'C4'), ('A4', 'B3', 'C3'), ('A4', 'B4', 'C2'), ('A5', 'B3', 'C4'), ('A2', 'B5', 'C3'), ('A5', 'B2', 'C2'), ('A5', 'B4', 'C3'), ('A4', 'B3', 'C1'), ('A3', 'B2', 'C5'), ('A2', 'B5', 'C5'), ('A4', 'B5', 'C5'), ('A5', 'B5', 'C5'), ('A3', 'B4', 'C5'), ('A3', 'B4', 'C5'), ('A5', 'B4', 'C2'), ('A2', 'B3', 'C1'), ('A2', 'B5', 'C2'), ('A3', 'B4', 'C4'), ('A4', 'B5', 'C1'), ('A3', 'B2', 'C2'), ('A4', 'B3', 'C5'), ('A2', 'B3', 'C3'), ('A3', 'B4', 'C1'), ('A5', 'B5', 'C4'), ('A3', 'B5', 'C5'), ('A3', 'B2', 'C5'), ('A5', 'B5', 'C3'), ('A5', 'B5', 'C3'), ('A3', 'B4', 'C4'), ('A4', 'B1', 'C1'), ('A3', 'B3', 'C4'), ('A4', 'B2', 'C5'), ('A5', 'B5', 'C5'), ('A4', 'B4', 'C3'), ('A1', 'B5', 'C3'), ('A4', 'B5', 'C3'), ('A4', 'B4', 'C2'), ('A5', 'B2', 'C2'), ('A5', 'B2', 'C5'), ('A4', 'B3', 'C5'), ('A4', 'B5', 'C1'), ('A4', 'B3', 'C5'), ('A5', 'B5', 'C5'), ('A3', 'B5', 'C3'), ('A5', 'B4', 'C5'), ('A3', 'B1', 'C4')]

print(sampleCombinations([1, 2], [1, 2], [1, 2], 3))
# [(2, 2, 2), (2, 2, 2), (1, 1, 1)]

相关问题 更多 >

    热门问题