Information theory problem, sets of numbers 信息论问题,数集

huangapple go评论55阅读模式
英文:

Information theory problem, sets of numbers

问题

我只有32位的空间来存储一组物品的组合。约束条件是一个组合可以有0到7个物品。有64种唯一的物品。一个物品不能在一个组合中多次出现。

如何将这些物品的集合映射到32位整数?

英文:

I only have 32 bits of space to store a combination of items. The constraints are that a combination can have anywhere from 0 to 7 items. There are 64 unique items. An item cannot appear multiple times in a combination.

How do I map these sets of items to 32-bit integers?

答案1

得分: 0

我要假设你所说的"combination"指的是一个集合。集合的顺序并不重要。如果顺序很重要,那么可能性就无法适应32位。

对于包含0到7个元素的集合,共有64个可能的元素,我们可以计算0到7个元素的二项式和(binomial(64, i),其中i在0到7之间),这总共有704,494,193种可能性。这甚至可以用30位表示(2^30 = 1,073,741,824)。

只需定义一个方案,为每种可能性分配唯一的编号并存储该编号。例如,为零元素分配0,为一个元素分配1到64,为两个元素分配65到2080,依此类推。

英文:

I have to assume that by a "combination" you mean a set. The ordering of a set does not matter. If the ordering matters, then the possibilities cannot fit in 32 bits.

For set of 0 to 7 elements, where there are 64 possible elements, we have that there are the sum of binomial(64,i) for i in 0..7 possibilities, which is 704,494,193. That would even fit in 30 bits (2<sup>30</sup> = 1,073,741,824).

Simply define a scheme that numbers each possibility uniquely and store that number. E.g. assign 0 for zero elements, 1..64 for one element, 65..2080 for two elements, and so on.

答案2

得分: 0

nth_combination 源自 itertools recipes(本页底部),它将从 32 位数字转换为特定组合,但是 itertools recipes 页面上未包含逆函数。下面概述的 combination_index 函数接受组合并返回该组合的索引。

这两个函数可以作为基础用于计算幂集的索引。这解决了原始问题,允许 r 的范围从 0 到 7。索引需要按前面组合的总组合数进行偏移。对于 r = 7,索引偏移将添加每个先前组合,即 math.comb(64, 0) + math.comb(64, 1) + math.comb(64, 2) + math.comb(64, 3) + math.comb(64, 4) + math.comb(64, 5) + math.comb(64, 6)。

import math
import itertools

# 这是 nth_combination 函数的逆函数
# 即 combination_index("abcd", nth_combination("abcd", 2, 3)) 返回 3
def combination_index(iterable, combination):
    # 组合必须按与可迭代对象相同的顺序排序
    # r 必须小于或等于 n
    pool = tuple(iterable)
    n = len(pool)
    r = len(combination)
    
    result = 0
    index = 0
    for i, item in enumerate(pool):
        if (item != combination[index]):
            result += math.comb(n - i - 1, r - index - 1)
        else:
            index += 1
        if (index >= len(combination)):
            break
    return result
英文:

nth_combination comes from the itertools recipes (at the bottom of this page). It converts from the 32 bit number to a specific combination however, the inverse function is not included on the itertools recipes page. combination_index outlined below takes in the combination and returns the index of that combination.

These two functions can be used as a base to calculate an index into the power set. Which solves the original question, allowing r to range from 0 to 7. The index needs to be shifted by the total combinations of the previous combinations. The index shifting for r = 7 would add each of the previous combinations aka math.comb(64, 0) + math.comb(64, 1) + math.comb(64, 2) + math.comb(64, 3) + math.comb(64, 4) + math.comb(64, 5) + math.comb(64, 6).

import math
import itertools

# this is the inverse of the nth_combination function
# aka. combination_index(&quot;abcd&quot;, nth_combination(&quot;abcd&quot;, 2, 3)) returns 3
def combination_index(iterable, combination):
    # combination must be sorted in the same order as the iterable 
    # r must be less than or equal to n
    pool = tuple(iterable)
    n = len(pool)
    r = len(combination)
    
    result = 0
    index = 0
    for i, item in enumerate(pool):
        if (item != combination[index]):
            result += math.comb(n - i - 1, r - index - 1)
        else:
            index += 1
        if (index &gt;= len(combination)):
            break
    return result

huangapple
  • 本文由 发表于 2023年5月10日 12:42:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76214956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定