称假币问题实验报告

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

称假币问题实验报告

——信息论第一次作业

学校:西安电子科技大学

班别:1307011班

姓名:***

学号:***********

一、问题重述

盒中有n个外形相同的硬币,知道其中有一个重量不同的硬币,但不知是比真币轻,还是比真币重。现用一无砝码天枰对现有硬币进行称重来鉴别假币,无砝码天枰的称重有3种结果,平衡,向左倾,向右倾。当n=12;n=39;n=n时,如何称重使实验次数最少,鉴别出假币并判断出轻或重?

二、问题分析

根据熵的可加性,一个复合事件的平均不确定性可以通过多次试验逐步解除。如果我们使实验所获得的信息量最大,那么所需要的总试验次数就最少。

(1)每一次使用天平,可以得到三种可能,左偏,右偏,平衡,而且这三种可能是概率相等的,所以每一次使用天平的结果都携带log3的信息量。

(2)要从N个硬币中找到那个不一样,可以有2N种概率相同的可能,每个硬币都可能偏轻或者偏重,这个事件所携带的信息量是log2N。

所以可以得到最少可以使用log2N/log3次天平就可以凑够信息量,指出哪一个是不一样的。

三、问题解决

【问题一】n=12

设12个硬币的编号分别为:1,2,3,4,5,6,7,8,9,10,11,12.三次称重安排如下表:

设3种称重结果分别表示为:0:平衡,1:左重,-1:右重。得到如下鉴别结果:

参见上面表格,可用矩阵表示3次称重的安排,矩阵上面标明12次硬币的序号,矩阵

的3行分别表示3次连续称重时硬币的放置状态,1表示放到左盘,-1表示放到右盘,0表示放到旁边(不参与称重)。

1234567891011121111-1-1-1-10

01000-11110-1-1-101-1011-10-11-10⎛⎫

⎪ ⎪⎝

⎭ 比较上面的表格和矩阵,发现:如果检测结果与上面矩阵的某列符合,则对应序号的硬币为

假币,且重量较重;如果检查结果与不包含在上述矩阵的列中,则1、-1互换,得到假币对应序号,但重量较轻。

【问题二】n=39

查阅资料得到,n 次称量最多可以在个球中找到不同的球,并判断它的轻重。 (1)编码:

知道了球数,就能算出需要称量几次;

以这个次数作为长度,使用0、1、2排列组合进行编码,如001021、212022等等,再去掉全0、全1和全2,可知一共有个编码;

如果在一个编码中,第一处相邻数字不同的情况是01、12或20,则我们称它为正序码,如1120021;

否则为逆序码,如2221012;

在长度为n 的编码中,正序码和逆序码的数量相等,均为个。 (2)赋值:

如果把一个正序码中的0换成1,1换成2,2换成0,则它仍然是正序码;

根据这个原理,我们把所有正序码按3个3个进行分组,如12001、20112、01220这3个就是一组;

把正序码一组一组地分配给小球,每球一个,直到分完;

然后把每个正序码的0换成2,2换成0,它就变成了一个逆序码,如12001变成10221; 这样,每个小球就有了两个编码,一个正序,一个逆序,而且所有球都不重复。 (3)称重:

第一轮,我们把所有正序码第一位为0的小球放在天平左侧,为2的小球放在右侧,其它的放在旁边;

如果天平左倾,记为0;右倾,记为2;平衡,记为1;

然后是第二轮,把第二位为0的小球放在左侧,为2的放在右侧,同样记下称量结果; 每一轮都按这个顺序进行,一共要称n 次,最终结果是个n 位的编码; 如果编码等于某个小球的正序码,则这个小球比其它球重; 如果编码等于某个小球的逆序码,则这个小球比其它球轻。

【问题三】n=n

方法与问题二同

四、算法演示

以n=12为例

(1)编号

(2)称重

正序码第一位为0的硬币放在天枰的左侧,第一位为2的放在右侧,第一位为1的放在旁边

结果与事先挑选的硬币一致

五、编写代码

#include

#include

#include

#include

#include

#include

using namespace std;

set sett;

int k,num,n,m;

int vsi[10005],weight[10005],fflag,s2i[10005],heavy_or_light; char s[10005][1005],rcd[10005];

int p=1,integ,leicheng=1;

void ten2three(int a,char *s)

{

num=0;

for(int i=0;i

s[i]='0';

while(1)

{

s[num++]=a%3+'0';

a/=3;

if(a<=1)

{

s[num]=a+'0';

break;

}

}

}

int judge1(int a)

{

char sss[3][10005];

int integ[3];

ten2three(a,sss[0]);

integ[0]=atoi(sss[0]);

for(int i=0;i

{

if(sss[0][i]=='0')

sss[1][i]='1';

else if(sss[0][i]=='1')

sss[1][i]='2';

else if(sss[0][i]=='2')

sss[1][i]='0';

}

integ[1]=atoi(sss[1]);

for(int i=0;i

{

if(sss[1][i]=='0')

sss[2][i]='1';

else if(sss[1][i]=='1')

sss[2][i]='2';

else if(sss[1][i]=='2')

sss[2][i]='0';

}

integ[2]=atoi(sss[2]);

int ok=1;

for(int i=0;i<=2;i++)

if(vsi[integ[i]])

{

ok=0;

break;

}

相关文档
最新文档