声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 3697|回复: 4

[经典算法] 求viterbi算法实例

[复制链接]
发表于 2005-10-19 23:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
求viterbi算法实例!

[ 本帖最后由 xinyuxf 于 2007-6-7 10:11 编辑 ]
回复
分享到:

使用道具 举报

发表于 2005-10-20 08:20 | 显示全部楼层

回复:(jftaoh)求viterbi算法实例!!!!

不知道你说的算法实例是什么意思?是viterbi的应用程序?还是viterbi算法的源程序?<BR><BR>/* viterbi.cpp jdg 2005/04/20 <BR>一个(k,n,K)的卷积码的维特比译码算法 <BR>*/<BR>#define k 1 //一次输入序列的长度<BR>#define n 3 //一次输出序列的长度<BR>#define K 3 //约束长度<BR>#define DECODER_STATES 4 //状态数2^(K-1)*k<BR>#define BRANCH_NUM 2 //从一个状态延伸的分支数<BR>#define PATH_LENGTH 16 //路径保留长度<BR>#include <STDLIB.H><BR>#include "stdafx.h"<BR>//#include "viterbi.h"<BR>//#include "encode.cpp"<BR>//#include "randsource.cpp"<BR>/* 多项式生成 g1=1[00000001](1) ,<BR>g2=x^2+1[00000101](5),<BR>g3=x^2+x^1+1[00000111](7) <BR><BR>*/<BR>int g[n][K*k]={1,0,0,<BR>1,0,1,<BR>1,1,1 };<BR><BR>//-------------------------------分支结构定义<BR>struct branch<BR>{<BR>int state_index,//状态索引<BR>input[k],//输入信息<BR>output[n];//输出码子<BR>double cm; //量度<BR>};<BR><BR>//------------------------------状态结构定义<BR>struct state<BR>{ <BR>double sum_cm;//累积量度<BR>struct branch branchs[BRANCH_NUM];//下一个状态数组<BR>int survivor[PATH_LENGTH]; //幸存路径<BR>struct branch best_branch; //到达的2^k条分支中最好的一条<BR><BR>}; <BR>state states[DECODER_STATES];<BR><BR>//------------------------------二进制随机信源生成函数<BR><BR>int randsource(int *x,int length)<BR>{ int i;<BR>printf("正在生成长度为 %d 的二进制的随机数序列x[] 。。。\n",length);<BR>for(i=0; i<LENGTH; i++) <BR> {<BR>if (i%10==0) printf("\n");<BR>*(x+i)= rand() % 2;<BR>printf("%d,", *(x+i) );<BR>}<BR>return 0; <BR>}<BR><BR>//------------------------------把整数变成数组向量函数<BR>int int_to_vector(int x,int *vector,int vlength)<BR>{<BR>int i;<BR>for(i=0;i<VLENGTH;I++)<BR> *(vector+i)=x&gt;&gt;i&amp;1;<BR>return 0;<BR>}<BR><BR>//------------------------------计算分支量度,cm=cm+Rjm*(2*Cjm-1);<BR>double compute_cm(int *r,int *c) <BR>{<BR>int x;<BR>double cm=0.0;<BR>for(x=0;x<N;X++) <BR>cm+=r[x]*(2*c[x]-1);<BR>//cm+=(r&gt;&gt;x)*(2*(c&gt;&gt;x)-1);<BR>return cm;<BR>}<BR><BR>//编码函数,input输入,ilength输入长度,output输出,olength输出长度,,currentstate当前状态<BR>int con_encode(int *input ,int ilength,int *output,int olength ,int *currentstate)<BR>{<BR>int out[n],<BR>i,j,x,p=0, //循环变量<BR>reg[K*k]; //移位寄存器<BR>for(i=0;i<ILENGTH k;i++) 对每k位输入bit循环<BR>{<BR>for(j=0;j<K;J++) <BR 把输入的k位bit送入移位寄存器> reg[j]=*(input+i+j); <BR>for (j=k;j<K*K;J++) 把当前状态放人移位寄存器<BR>reg[j]=*(currentstate+j-k); <BR>for(j=0;j<K*K;J++) <BR 生成输出的n位bit信息>{<BR>for(x=0;x<N;X++)<BR>out[x]+=g[x][j]^reg[j];<BR>}<BR>for(x=0;x<N;X++)<BR>{<BR>*(output+p)=out[x];<BR>p++;<BR>if (p&gt;olength) <BR>printf("\n 输出长度超过预定义输出数字长度,请检查输出数组定义!\n");<BR>}<BR><BR>for(j=0;j&lt;(K-1)*k;j++)<BR>*(currentstate+j)=reg[j];<BR>}<BR><BR>return 0;<BR><BR>}<BR><BR>/* <B >Viterbi算法</B>解卷积码函数,参数说明<BR>r:解调输出序列,<BR>rlength:r的长度<BR>decode:解码后的序列<BR>dlength:decode的长度<BR>*/<BR>int ViterbiDecode(int *r,int rlength,int *decoded,int dlength)<BR>{<BR>int i,j,x,y;<BR>int rm[n],//接收向量<BR>cur_state[(K-1)*k];//当前状态向量<BR>double temp_cm,temp_sum_cm[DECODER_STATES];//临时量度<BR>int *temp_input[DECODER_STATES];//临时变量<BR>int one=0,zero=0;<BR>//各状态初始化<BR>for (i=0;i<DECODER_STATES;I++)<BR>{<BR>states.sum_cm=-65535;<BR>for(j=0;j<BRANCH_NUM;J++)<BR>{<BR>states.branchs[j].state_index=i&lt;<K^J;<BR> int_to_vector(j,states.branchs[j].input,k);<BR>int_to_vector(i,cur_state,(K-1)*k);<BR>con_encode(states.branchs[j].input,k,states.branchs[j].output,n ,cur_state);<BR>}<BR><BR>for(j=0;j<PATH_LENGTH;J++)<BR>states.survivor[j]=-1;<BR>}<BR>states[0].sum_cm=0.0;<BR>//-----------------------------初始化完毕<BR>//-----------------------------对每个接收的n维矢量循环<BR>for (x=0;x<RLENGTH <BR n;x++)>{ <BR><BR>for (i=0;i<N;I++) 从接收序列中取出一个码子的长度<BR>rm=*(r+x+i);<BR><BR>for (i=0;i<DECODER_STATES;I++) 对每个状态循环<BR>{<BR>for (j=0;j<DECODER_STATES;J++)<BR>{<BR>for(y=0;y<BRANCH_NUM;Y++)<BR>{<BR>if (states[j].branchs[y].state_index==i)<BR>{<BR>//计算分支量度<BR>temp_cm=states[j].sum_cm+compute_cm(rm,states[j].branchs[y].output);<BR>if (temp_sum_cm<TEMP_CM) <BR>{<BR>temp_sum_cm=temp_cm;<BR>temp_input=states[j].branchs[y].input;<BR>}<BR>break;<BR>}<BR>}<BR>}<BR><BR>}<BR>for(i=0;i<K;I++)<BR> *(decoded+x+i)=states[0].survivor[PATH_LENGTH-1-i];<BR>for (i=0;i<DECODER_STATES;I++) <BR> {<BR>states.sum_cm=temp_sum_cm;<BR>for(j=PATH_LENGTH-1;j&gt;k-1;j--)<BR>states.survivor[j]=states.survivor[j-k];<BR>for (j=0;j<K;J++)<BR> states.survivor[k-1-j]=*(temp_input+j);<BR>}<BR>}<BR>return 0;<BR><BR>}<BR><BR>int _tmain(int argc, _TCHAR* argv[])<BR>{<BR>//int i;<BR>int x[100];<BR>randsource(x,100);<BR>/*<BR>printf("encoded stream...\n");<BR>for(i=0;i&lt;100;i++)<BR>{<BR>printf(" %d " ,con_encode(1));<BR>}<BR>printf("\n decoded stream...\n");<BR>for(i=0;i&lt;100;i++)<BR>{<BR>printf(" %d",ViterbiDecode(con_encode(1)));<BR>}<BR>*/<BR><BR>return 0;<BR>} <BR>
 楼主| 发表于 2005-10-20 19:49 | 显示全部楼层

先得谢谢你,最好是应用实例!

谢谢!
发表于 2005-10-20 20:58 | 显示全部楼层

回复:(jftaoh)求viterbi算法实例!!!!

孙健的博士论文中有一个命名实体识别的实例其识别过程用的就是viterbi算法,你可以找来看看
[此贴子已经被作者于2005-10-20 20:58:15编辑过]

发表于 2006-4-20 23:37 | 显示全部楼层

求卷积码的viterbi译码算法实例!!!!

上面的例子有些地方不太完整,看不太明白,恳请发送完整的源程序!不胜感激!!!!
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-10 09:30 , Processed in 0.143237 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表