计算熵


13

输入值

M表示为两条以空格分隔的整数行的矩阵。每条线将具有相同数目的整数,并且每个整数将是-1或1为至多20每行的整数的数目 M因此将2通过n其中n在每两行的整数的个数。

您的代码应该是完整的程序。并接受标准输入或来自文件的输入(您可以选择)。您可以接受标准输入,文件输入或仅作为参数输入。但是,如果您选择后者,请给出一个代码示例,以明确说明该代码如何工作,并记住它必须是一个完整的程序,以及矩阵M将如何在输入中表示。换句话说,您可能必须进行一些解析。

输出量

所述二进制信息熵的分布M*x,其中的元素x均匀地和独立地选自{-1,1}选择。 x是一个n三维列向量。

离散概率分布的熵为

- sum p_i log_2(p_i)

在这种情况下,p_i是的概率i个独特的可能M*x

示例和有用的提示

作为一个工作示例,让矩阵M

-1 1
-1 -1

现在来看所有2^2可能的向量x。对于每一个,我们计算M*x所有结果并将其放入一个数组(2分量向量的4元素数组)中。尽管对于这四个向量中的每个向量,其出现的概率为1/2^2 = 1/4,但我们仅对每个唯一的结果向量M*x出现的次数感兴趣,因此,我们总结了导致相同的唯一向量的配置的各个概率。换句话说,可能的唯一M*x向量描述了我们正在研究的分布的结果,并且我们必须确定这些结果中的每一个的概率(根据构造,该概率始终是1/2^2或通常是的整数倍1/2^n),计算熵。

在一般n情况下,取决于can M的可能结果,其M*x范围从“所有不同”(在这种情况下,我们具有in的n值,每个值等于)到“所有相同”(在这种情况下,可能存在一个结果)。ip_ip_i1/2^np_1 = 1

具体来说,对于上述2x2矩阵,M我们可以通过将其乘以四个可能的配置([+-1; +-1])来发现,每个结果向量都是不同的。因此,在这种情况下,有四个结果p_1 = p_2 = p_3 = p_4 = 1/2^2 = 1/4。回顾log_2(1/4) = -2我们有:

- sum p_i log_2(p_i) = -(4*(-2)/4) = 2

因此,此矩阵的最终输出为2。

测试用例

输入:

-1 -1 
-1 -1

输出:

1.5

输入:

-1 -1 -1 -1
-1 -1 -1 -1

输出:

2.03063906223

输入:

-1  -1  -1  1
1  -1  -1  -1

输出:

3

7
1.的尺寸是x多少?2.为了使问题变得独立,如何Mx定义二进制香农熵?
彼得·泰勒

4
@Peter的评论正好解释了反对意见。我浏览了有关熵的文章,但我无法立即找出要实现的内容。您应该确切指定计算香农熵的公式/算法。
林恩(Lynn)2015年

5
无论如何,问题应该是独立的;维基百科不太可能突然下线,但是理想的情况是不必单击进入另一个页面就能了解挑战的完整说明。
门把手

2
默认情况下,函数是程序的有效替代方法。您可以推翻该规则,但这会使某些语言感到非常难过,因为它需要很多样板文件或文件输入。更广泛地说,我建议不要在数学难题上使用这种限制性输入格式。允许该语言的自然列表类型将使人们更乐于参与。
xnor 2015年

3
@dorothy注意,不是为了方便起见,“ log_2(0)为0”,而是“ lim_ {p-> 0} p * log(p)== 0”。因此,“ log_2(0)”仍然是-inf。
Andras Deak

Answers:


3

Mathematica,48 68字节

编辑:添加了预处理,以接受字符串作为参数。

的帮助下TuplesEntropy,实施既简明易读。

Entropy[2,{-1,1}~Tuples~Length@#.#]&@Thread@ImportString[#,"Table"]&

其中Tuples[{-1,1},n]给出的所有可能n元组{-1,1},并Entropy[2,list]给出以2为底的信息熵。

一件很酷的事情是Mathematica实际上会返回一个准确的表达式:

%["-1 -1 \n -1 -1"]
(* 3/2 *)

额外.添加(Entropy[2., ...)即可获得近似结果。


Mathematica太荒谬了:)但是您的答案并不完全符合规范。输入是空格分隔的,因此需要一些解析。查看最新更新。
dorothy

3

Perl中,160个 159 141字节

-p自141字节更新以来包括+1

@y=(@z=/\S+/g)x 2**@z;@{$.}=map{evals/.1/"+".$&*pop@y/egr}glob"{-1,+1}"x@z}{$H{$_.$2[$i++]}++for@1;$\-=$_*log($_/=1<<@z)/log 2 for values%H;

预期输入STDIN为2行,由空格1或组成-1
运行为perl -p 140.pl < inputfile

它不会赢得任何奖项,但我想我会尽我的努力。
解释:

    @y=                             # @y is (@z) x (1<<$n)
       (@z = /\S+/g)                # construct a matrix row from non-WS
       x 2**@z;                     # repeat @z 2^$n times
    @{$.} = map {                   # $.=$INPUT_LINE_NUMBER: set @1 or @2
      eval s/.1/"+".$&*pop@y/egr    # multiply matrix row with vector
    } glob "{-1,+1}" x @z           # produce all possible vectors

}{                                  # `-p` trick: end `while(<>)`, reset `$_`

$H{ $_ . $2[$i++] }++               # count unique M*x columns
    for @1;

$\ -= $_ * log($_/=1<<@z) / log 2   # sum entropy distribution
        for values %H;

数据

  • 更新159:()通过使用**代替来节省1 <<
  • 更新141:使用$.和保存18 -p

1
谢谢!我们没有关于ppcg imho的perl答案
dorothy

@dorothy这是因为在大多数情况下,代码高尔夫球手讨厌 Perl。
Addison Crump

@FlagAsSpam但是,.. perl令人费解,简洁而疯狂。怎么可能适合代码高尔夫?
dorothy

@dorothy¯\ _(ツ)_ /¯我们像瘟疫一样避免了它。邓诺,为什么,真的。
Addison Crump

2

Pyth,37个字节

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8

测试套件

当您必须手动实现矩阵乘法时,这有些棘手。

说明:

K^_B1lhJrR7.z_s*LldcRlKhMrSmms*VdkJK8
       JrR7.z                            Parse input into matrix, assign to J.
  _B1                                    [1, -1]
K^   lhJ                                 All +-1 vectors of length n, assign to K.
                           m       K     Map over K
                            m     J      Map over the rows of J
                             s*Vdk       Sum of vector product of vector and row.
                          S              Sort
                         r          8    Run length encode.
                       hM                Take just occurrence counts.
                   cRlK                  Divide by len(K) to get probabilities.
               *Lld                      Multiply each probabiliity by its log.
              s                          Sum.
             _                           Negate. Print implicitly.

哇!:)这看起来像很多工作。现在果酱人在哪里.....?
dorothy

1

MATLAB,196个 194 187 184 126 154字节

(从126到154的额外28个字节是由于输入解析:现在,代码将输入接受为两行以空格分隔的数字。)

f=@()str2num(input('','s'));M=[f();f()];n=size(M,2);x=(dec2bin(0:n^2-1,n)-48.5)*2*M';[~,~,c]=unique(x,'rows');p=accumarray(c,1)/2^n;disp(-sum(p.*log2(p)))

非高尔夫版本:

f=@()str2num(input('','s'));        % shorthand for "read a line as vector"
M=[f();f()];                        % read matrix
n=size(M,2);                        % get lenght of vectors

x=(dec2bin(0:n^2-1,n)-48.5)*2*M';   % generate every configuration
                                    %    using binary encoding
[~,~,c]=unique(x,'rows');           % get unique rows of (Mx)^T
p=accumarray(c,1)/2^n;              % count multiplicities and normalize
disp(-sum(p.*log2(p)))              % use definition of entropy

如果允许“ ans = ...”类型的输出,我可以删除6个字节,但我对此不确定。

我很遗憾地说,与我当前的解决方案相比,我最初的,肯定是机智的解决方案实在太离谱了。这也是我第一次使用accumarray。六输入参数的应用程序仍然需要等待,但是:)

输出(以下format long):

[-1 1
-1 -1]
     2

[-1 -1
-1 -1]
   1.500000000000000

[-1 -1 -1 -1
-1 -1 -1 -1]
   2.030639062229566

[-1  -1  -1  1
1  -1  -1  -1]
     3

输出为默认值format short g

[-1 1
-1 -1]
     2

[-1 -1
-1 -1]
          1.5

[-1 -1 -1 -1
-1 -1 -1 -1]
       2.0306

[-1  -1  -1  1
1  -1  -1  -1]
     3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.