简体   繁体   English

计算具有最小和最大差异的唯一正整数的组合数量?

[英]Calculate the number of combinations of unique positive integers with minimum and maximum differences between each other?

How do I write a Python program to calculate the number of combinations of unique sorted positive integers over a range of integers that can be selected where the minimum difference between each of the numbers in the set is one number and the maximum difference is another number? 我如何编写Python程序来计算在整数范围内唯一排序的正整数组合的数量,该整数范围内集合中每个数字之间的最小差是一个数字而最大差是另一个数字?

For instance, if I want to calculate the number of ways I can select 6 numbers from the positive integers from 1-50 such that the minimum difference between each number is 4 and the maximum difference between each number is 7, I would want to count the combination {1,6,12,18,24,28} since the minimum difference is 4 and the maximum difference is 6, but I would not want to count combinations like {7,19,21,29,41,49} since the minimum difference is 2 and the maximum difference is 12. 例如,如果我想计算可以从1-50的正整数中选择6个数字的方式,以使每个数字之间的最小差为4,而每个数字之间的最大差为7,则我想计算组合{1,6,12,18,24,28},因为最小差异为4,最大差异为6,但我不想计算类似{7,19,21,29,41,49}的组合因为最小差异为2,最大差异为12。

I have the following code so far, but the problem is that it has to loop through every combination, which takes an extremely long time in many cases. 到目前为止,我有以下代码,但问题是它必须遍历每个组合,在许多情况下这要花费很长时间。

import itertools

def min_max_differences(integer_list):
    i = 1
    diff_min = max(integer_list)
    diff_max = 1
    while i < len(integer_list):
        diff = (integer_list[i]-integer_list[i-1])
        if diff < diff_min:
            diff_min = diff
        if diff > diff_max:
            diff_max = diff
        i += 1
    return (diff_min,diff_max)

def total_combinations(lower_bound,upper_bound,min_difference,max_difference,elements_selected):
    numbers_range = list(range(lower_bound,upper_bound+1,1))
    all_combos = itertools.combinations(numbers_range,elements_selected)
    min_max_diff_combos = 0
    for c in all_combos:
        if min_max_differences(c)[0] >= min_difference and min_max_differences(c)[1] <= max_difference:
            min_max_diff_combos += 1
    return min_max_diff_combos

I do not have a background in combinatorics, but I am guessing there is a much more algorithmically efficient way to do this using some combinatorial methods. 我没有组合技术的背景知识,但是我猜想有一种使用某些组合方法在算法上更有效的方法。

You can use a recursive function with caching to get your answer. 您可以将递归函数与缓存一起使用来获取答案。 This method will work even if you have a large array because some positions are repeated many times with the same parameters. 即使您的数组很大,此方法也将起作用,因为使用相同的参数将某些位置重复多次。
Here is a code for you (forgive me if I made any mistakes in python cause I don't normally use it). 这是给您的代码(如果我在python中犯了任何错误,请原谅我,因为我通常不使用它)。 If there is any flow in the logic, please let me know 如果逻辑上有任何流程,请告诉我

# function to get the number of ways to select {target} numbers from the 
# array {numbers} with minimum difference {min} and maximum difference {max}
# starting from position {p}, with the help of caching

dict = {}
def Combinations(numbers, target, min, max, p):
    if target == 1: return 1

    # get a unique key for this position
    key = target * 1000000000000 + min * 100000000 + max * 10000 + p

    if dict.has_key(key): return dict[key]

    ans = 0

    # current start value
    pivot = numbers[p]
    p += 1;
    # increase the position until you reach the minimum
    while p < len(numbers) and numbers[p] - pivot < min:
        p += 1

    # get all the values in the range of min <--> max
    while p < len(numbers) and numbers[p] - pivot <= max:
        ans += Combinations(numbers, target - 1, min, max, p)
        p += 1

    # store the ans for further inquiry
    dict[key] = ans
    return ans


# any range of numbers (must be SORTED as you asked)
numbers = []
for i in range(0,50): numbers.append(i+1)
# number of numbers to select
count = 6
# minimum difference
min = 4
# maximum difference
max = 7
ans = 0
for i in range(0,len(numbers)):
    ans += Combinations(numbers, count, min, max, i)
print ans

Here is a very simple (and non-optimized) recursive approach: 这是一种非常简单(且未优化)的递归方法:

Code

import numpy as np
from time import time

""" PARAMETERS """
SET = range(50) # Set of elements to choose from
N = 6           # N elements to choose
MIN_GAP = 4     # Gaps
MAX_GAP = 7     # ""

def count(N, CHOSEN=[]):
    """ assumption: N > 0 at start """
    if N == 0:
        return 1
    else:
        return sum([count(N-1, CHOSEN + [val])
                        for val in SET if (val not in CHOSEN)
                                       and ((not CHOSEN) or ((val - CHOSEN[-1]) >= MIN_GAP))
                                       and ((not CHOSEN) or ((val - CHOSEN[-1]) <= MAX_GAP))])

start_time = time()
count_ = count(N)
print('used time in secs: ', time() - start_time)
print('# solutions: ', count_)

Output 输出量

('used time in secs: ', 0.1174919605255127)
('# solutions: ', 23040)

Remarks 备注

  • It outputs the same solution as Ayman's approach 它输出与Ayman方法相同的解决方案
  • Ayman's approach is much more powerful (in terms of asymptotical speed) 艾曼(Ayman)的方法更强大(就渐近速度而言)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 numpy 数组中找到最大负数和最小正数? - How to find maximum negative and minimum positive number in a numpy array? 按递增顺序查找所有正整数组合,这些组合加起来等于给定的正数 n - Find all combinations of positive integers in increasing order that adds up to a given positive number n 从列表中创建一个子列表,该列表的最小和最大元素之间的正差最小 - make a sub-list from a list which has minimum positive difference between its minimum and maximum elements 使用唯一正整数填充DataFrame - Filling DataFrame with unique positive integers 最大数量组合 - maximum number combinations 如何生成介于最小和最大位数之间的随机数? (Python) - How to generate a random number between a minimum and maximum number of digits? (Python) 计算列表中每个单词的正负字符串数 - Calculate number of positive and negative string for each word in a list 获取每个给定范围之间的整数个数 - Get the number of integers between each given range 用每个城市的所有可能组合计算5个城市之间的地理距离 - Calculate geographical distance between 5 cities with all the possible combinations of each city 在给定的最大值和最小值之间重新缩放值,其中max为正,min为负 - re-scaling the values between given maximum and minimum, where max is positive and min is negative
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM