C语言找错误,200分答谢(为维特比译码程序)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言找错误,200分答谢(为维特比译码程序)相关的知识,希望对你有一定的参考价值。

#include "main.h"
// 微分真值表,第4和第5位用于发送,第0和第0位用于接收
char Diff[] =
0x00, 0x11, 0x23, 0x32, 0x11, 0x00, 0x32, 0x23, 0x22, 0x33, 0x10, 0x01, 0x33, 0x22, 0x01, 0x10 ;
// 延迟状态发送矩阵,用于回溯当前状态
char TMBackward[8][4] =
0, 3, 1, 2, 14
4, 7, 6, 5, 15
1, 2, 0, 3, 16
5, 6, 7, 4, 17
2, 1, 3, 0, 18
7, 4, 5, 6, 19
3, 0, 2, 1, 20
6, 5, 4, 7 21
;

char Tdr, DelayState[16][8], PathState[16][2], DStCurr;
int AccDist[8];
// 初始化函数
void Init ()

short i, j;
DStCurr = 0;
Tdr = 0;
AccDist[0] = 0;
for (i = 1; i < 8; i++)
AccDist[i] = (1 << 10) / 2;
for (j = 0; j < 16; j++)
for (i = 0; i < 8; i++)
DelayState[j][i] = 0;
for (j = 0; j < 16; j++)
for (i = 0; i < 2; i++)
PathState[j][i] = 0;

// 译码
int Viterbi (int Xi, int Yi, int modd)

short State[8], Xb, Yb, Nx, Ny, Qx, Qy, Ix, Iy, Id;
short c, i, j, tmp1, tmp2, tmp3, tmp4, tt, ss, pp;
int Distance[8], dist1, dist0, DataOut, Sht;
Mod *Mcurr;

Mcurr = (Mod*) modd;
Sht = Mcurr->TSht;
// Xi和Yi是输入,首先得到最低距离
for (c = 0; c < 8; c++)

Xb = (Mcurr->TXs[c]) << 10; Yb = (Mcurr->TYs[c]) << 10;
Nx = Mcurr->TNx[c]; Ny = Mcurr->TNy[c];
Qx = (Mcurr->TQx) << 10; Qy = (Mcurr->TQy) << 10;
Iy = Ny;
for (i = 0; i < Ny; i++)

if (Yi < Yb) Iy = i; break;
Yb += Qy;

Ix = Nx;
for (i = 0; i < Nx; i++)

if (Xi < Xb) Ix = i; break;
Xb += Qx;

Id = Iy * (Nx + 1) + Ix;
State[c] = *(Mcurr->St[c] + Id);
tmp1 = *(Mcurr->Xc[c] + Id);
tmp2 = *(Mcurr->Yc[c] + Id);
if (State[c] != SS)

tmp3 = Xi - (tmp1 << 10);
tmp4 = Yi - (tmp2 << 10);
Distance[c] = (int)tmp3 * (int)tmp3 + (int)tmp4 * (int)tmp4;

else

tmp3 = Xi - (*(Mcurr->Xc[c] + tmp1) << 10);
tmp4 = Yi - (*(Mcurr->Yc[c] + tmp1) << 10);
dist1 = (int)tmp3 * (int)tmp3 + (int)tmp4 * (int)tmp4;
tmp3 = Xi - (*(Mcurr->Xc[c] + tmp2) << 10);
tmp4 = Yi - (*(Mcurr->Yc[c] + tmp2) << 10);
Distance[c] = (int)tmp3 * (int)tmp3 + (int)tmp4 * (int)tmp4;
State[c] = *(Mcurr->St[c] + tmp2);
if (dist1 < Distance[c])

Distance[c] = dist1;
State[c] = *(Mcurr->St[c] + tmp1);

还有一半程序在这里,希望高手指教哪里错误http://zhidao.baidu.com/question/95437386.html

char TMBackward[8][5] =
0, 3, 1, 2, 14
4, 7, 6, 5, 15
1, 2, 0, 3, 16
5, 6, 7, 4, 17
2, 1, 3, 0, 18
7, 4, 5, 6, 19
3, 0, 2, 1, 20
6, 5, 4, 7 21
;
参考技术A char TMBackward[8][4] =
0, 3, 1, 2, 14
4, 7, 6, 5, 15
1, 2, 0, 3, 16
5, 6, 7, 4, 17
2, 1, 3, 0, 18
7, 4, 5, 6, 19
3, 0, 2, 1, 20
6, 5, 4, 7 21
;///////////////////////////////越界了
参考技术B 定义的数组char TMBackward[8][4] 是8行4列字符型数组,数值范围在-128-127
你定义的里面有5列,,,,最后721?是不是7,21???
参考技术C char TMBackward[8][5] =
0, 3, 1, 2, 14
4, 7, 6, 5, 15
1, 2, 0, 3, 16
5, 6, 7, 4, 17
2, 1, 3, 0, 18
7, 4, 5, 6, 19
3, 0, 2, 1, 20
6, 5, 4, 7 21
; 多多保函,不大好。

自然语言处理之维特比(Viterbi)算法

点击蓝色字订阅,每天与您一起学习成长

维特比算法 (Viterbi algorithm) 是机器学习中应用非常广泛的动态规划算法,在求解隐马尔科夫、条件随机场的预测以及seq2seq模型概率计算等问题中均用到了该算法。实际上,维特比算法不仅是很多自然语言处理的解码算法,也是现代数字通信中使用最频繁的算法。在介绍维特比算法之前,先回顾一下隐马尔科夫模型,进而介绍维特比算法的计算步骤


1. 维特比算法


以下为一个简单的隐马尔科夫模型,如下图所示:

自然语言处理之维特比(Viterbi)算法

其中x = (x1, x2, ..., xN) 为隐状态序列,y = (y1, y2, ..., yN) 为观测序列,要求的预测问题为:

自然语言处理之维特比(Viterbi)算法

依据马尔科夫假设,上式等价于:

自然语言处理之维特比(Viterbi)算法

在隐马尔科夫链中,任意时刻t下状态的值有多个,以拼音转汉字为例,输入拼音为“yike”可能有的值为一棵,一刻或者是一颗等待,用符号xij表示状态xi的第j个可能值,将状态序列按值展开,就得到了一个篱笆网了,这也就是维特比算法求解最优路径的图结构:

自然语言处理之维特比(Viterbi)算法

隐马尔科夫的预测问题就是要求图中的一条路径,使得该路径对应的概率值最大。 对应上图来讲,假设每个时刻x可能取的值为3,如果直接求的话,有3^N的组合数,底数3为篱笆网络宽度,指数N为篱笆网络的长度,计算量非常大。维特比利用动态规划的思想来求解概率最大路径(可理解为求图最短路径),使得复杂度正比于序列长度,复杂度为O(NDD), N为长度,D为宽度,从而很好地解决了问题的求解。


维特比算法的基础可以概括为下面三点(来源于吴军:数学之美): 


1、如果概率最大的路径经过篱笆网络的某点,则从开始点到该点的子路径也一定是从开始到该点路径中概率最大的。 


2、假定第i时刻有k个状态,从开始到i时刻的k个状态有k条最短路径,而最终的最短路径必然经过其中的一条。 


3、根据上述性质,在计算第i+1状态的最短路径时,只需要考虑从开始到当前的k个状态值的最短路径和当前状态值到第i+1状态值的最短路径即可,如求t=3时的最短路径,等于求t=2时的所有状态结点x2i的最短路径加上t=2到t=3的各节点的最短路径。


为了纪录中间变量,引入两个变量sigma和phi,定义t时刻状态为i的所有单个路径 (i1, i2, ..., it) 中最大概率值(最短路径)为(前文小修已经有介绍隐马尔科夫相关的概念,如果不清楚可以看一下前面的 ):

自然语言处理之维特比(Viterbi)算法

其中it表示最短路径,Ot表示观测符号,lamda表示模型参数,根据上式可以得出变量sigma的递推公式:

自然语言处理之维特比(Viterbi)算法

其中i = 1, 2, ..., N; t = 1, 2, ... , T-1,定义在时刻t状态为i的所有单个路径 (i1, i2, ..., it, i) 中概率最大的路径的第t-1个结点为:

自然语言处理之维特比(Viterbi)算法

根据上面的两个定义下面给出维特比算法具体内容:

输入为模型和观测状态分别为:

自然语言处理之维特比(Viterbi)算法自然语言处理之维特比(Viterbi)算法

输出为求出最优路径:

自然语言处理之维特比(Viterbi)算法

步骤为:(1) 初始化各参数:

自然语言处理之维特比(Viterbi)算法

(2) 根据上式进行递推,对t=2, 3, ..., T

自然语言处理之维特比(Viterbi)算法

(3) 最后计算终止状态:

自然语言处理之维特比(Viterbi)算法

最优路径的回溯,对t=T-1, T-2,..., 1

自然语言处理之维特比(Viterbi)算法

最后求得最优路径:

自然语言处理之维特比(Viterbi)算法

以上就是维特比算法的主要过程和内容,下面介绍两个例子。

2. 马尔科夫模型状态序列例子

假设有三个不同的盒子,每个盒子里面有两种不一样的球分别为红色和白色球,按照下面的方法抽球,产生一个球的颜色的观测序列:从三个盒子里以等概率随机抽取一个盒子,从这个盒子里随机抽取一个球,纪录其球的颜色,放回,然后再选择一个盒子重复上述过程,可以得到一个观察到的球的颜色的序列O=(红,白,红),其中该过程中的初始概率分布Pai,状态转移概率分布A,以及观测概率B分别为:

自然语言处理之维特比(Viterbi)算法

是求解最优状态序列,最优选择盒子的顺序路径。

根据维特比算法,先初始化各值,在t=1时,对每一个状态i,i=1,2,3,求状态i观测O1为红色的概率,则:

自然语言处理之维特比(Viterbi)算法

代入实际数据可以得到:

自然语言处理之维特比(Viterbi)算法

记:

自然语言处理之维特比(Viterbi)算法

第二步,在t=2时对每个状态i,i=1,2,3, 求在t=1时状态为j观测为红并在t=2时状态为i观测O2为白的路径的最大概率,记此最大概率为:

自然语言处理之维特比(Viterbi)算法

同时对于每隔状态i,i=1,2,3,纪录概率最大路径的前一个状态j为:

自然语言处理之维特比(Viterbi)算法

计算得到:

自然语言处理之维特比(Viterbi)算法

同样在t=3时,有:

自然语言处理之维特比(Viterbi)算法

最后一步,计算最优路径的概率为:

自然语言处理之维特比(Viterbi)算法

因此最优路径的终点i3为:

自然语言处理之维特比(Viterbi)算法

最后根据找到的最优路径的终点,逆向找到每个结点的结果,于是求得最优状态序列为:

自然语言处理之维特比(Viterbi)算法

其求解过程中的图为:

自然语言处理之维特比(Viterbi)算法

3. seq2seq模型中维特比算法应用

在自然语言处理技术中的seq2seq模型中,如下图所示:

自然语言处理之维特比(Viterbi)算法

其实seq2seq模型的核心就是:

自然语言处理之维特比(Viterbi)算法

其中e和f就是相应的输出和输入序列,在进行解码的时候,如果词袋中的个数为V个,那么那么输出长度为N的序列,则需要的总共搜索V^N次,如果N的个数非常之大,这样的搜索非常耗时间,那么这个时候使用维特比算法就会大大的降低搜索的时间。这里假设词袋中只有a和b,而且它们之间的转变概率为:

自然语言处理之维特比(Viterbi)算法


在这时使用维特比算法,其主要的思想为:

自然语言处理之维特比(Viterbi)算法

其中s(v,n) 表示的是以v结尾的最大概率的序列的概率,t(i, j, n)为第n-1步从i跳到第n步的j的概率。根据算法可以得到:

自然语言处理之维特比(Viterbi)算法

自然语言处理之维特比(Viterbi)算法

因此最终输出的序列为bba,


在这里最后说一点就是,其实对于seq2seq有相应的算法对整个序列的输出进行搜索计算 (beam search算法),其思想和维特比算法非常相似,这里不做介绍,下次有机会给大家介绍。


参考书目:

[1] 统计学习方法,李航


自然语言处理技术

自然语言处理技术为您推送精品阅读

每天一个知识点,健康生活每一天


以上是关于C语言找错误,200分答谢(为维特比译码程序)的主要内容,如果未能解决你的问题,请参考以下文章

翻译 | 卷积码的维特比(Viterbi)译码

FEC前向纠错,卷积编码之维特比译码

FPGA教程案例97信道编译码1——基于FPGA的卷积编码维特比译码verilog实现,MATLAB辅助验证

C语言实训

基于FFT的算法优化 要C语言完整程序(利用旋转因子的性质),有的请留言,答谢!!!(有核心代码,望指教

Python中文分词维特比算法为啥在输入字符超过一定长度后会发生错误