【问题标题】:Combinations with constraints find a repartitions that goes from low to high与约束的组合找到从低到高的重新分区
【发布时间】:2021-09-18 14:22:21
【问题描述】:

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

拥有三个项目列表:

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 少于2 来自 A、B、C。

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

我想为很多项目这样做。

【问题讨论】:

  • product() 做什么?需要import 吗?
  • “其中 A1 B1 C1 出现小于 A2 B2 C2”:您希望输出中有字母吗?如果你能给出更具体的例子来说明 "pretty linear repartition" 的含义会很好。
  • @p._phidot_ 是的,这是一个导入 from itertools import product
  • @trincot 对不起我的英语不好,在输出中我只想要数字的组合,例如 (1,2,3) , (1,3,4) ...知道这个例子将有 125 个独特的组合,我想选择 A,B,C 列表中的 1 较少的组合,以及 A,B,C 中包含 2 的较少组合。 ..我将重新制作一个更明确的示例
  • @trincot 我无法编辑我的帖子,因为我是 Stackoverflow 的新手。我将在这里重新制作示例。 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 代表三个项目列表。

标签: python algorithm generator combinations dynamically-generated


【解决方案1】:

我认为您的问题有点未明确说明,因此您可以选择要如何准确地加权组合。

一种可能性是选择随机组合,但i*j*k 的权重归因于组合[A[i],B[j],C[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

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)]

【讨论】:

  • 解决我的问题的好主意。我会考虑的,谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多