信道容量的迭代算法实现
#include <iostream>
using namespace std;
#define FLOAT_MINUS_PRECISION 0.00001
typedef vector<float*> VEC_PFLOAT;
//迭代计算信道容量,参数值为信源,信宿符号个数和信道转移概率矩阵,返回信道容量< /pre>
float GetCapacity(int nSourceSymbol,int nHostSymbol,const VEC_PFLOAT& vTransMatrix)
{
//信道容量初始化为最小值
float fCapacity = FLT_MIN;
//信源概率分布
float *pfSoureProb = new float[nSourceSymbol];
//初始化信源分布为均匀分布
int i;
for (i = 0; i < nSourceSymbol; i++)
{
pfSoureProb[i] = 1.0 / nSourceSymbol;
}
//初始化φ函数
VEC_PFLOAT vPhi;
for (i = 0; i < nSourceSymbol; i++)
{
float *pfTemp = new float[nHostSymbol];
vPhi.push_back(pfTemp);
}
//设置精度;
const float cfDelta = 0.02f;
float fPrecision;
//迭代计算
int j,k;
float *pfSum = new float[nSourceSymbol];
do
{
for (i = 0; i < nSourceSymbol; i++)
{
for (j = 0; j < nHostSymbol; j++)
{
//计算ΣPi*Pji
float fSum = 0.0f;
for (k = 0; k < nSourceSymbol; k++)
{
fSum += pfSoureProb[i] * vTransMatrix[k][i];
}
vPhi[i][j] = pfSoureProb[i] * vTransMatrix[j][i] / fSum;
}
}
float fSumDeno = 0.0f; //分母求和
for (i = 0; i < nSourceSymbol; i++)
{
float fSum = 0.0f;
for (j = 0; j < nHostSymbol; j++)
{
fSum += vTransMatrix[j][i] * logf(vPhi[i][j]);
}
pfSum[i] = expf(fSum);
fSumDeno += pfSum[i];
}
for (i = 0; i < nSourceSymbol; i++)
{
pfSoureProb[i] = pfSum[i] / fSumDeno;
}
//计算新一轮的容量
float fNewC = logf(fSumDeno);
//计算精度
fPrecision = fabs(fNewC - fCapacity) / fCapacity;
fCapacity = fNewC;
} while(fPrecision - cfDelta > 0.0f);
//释放临时资源
delete []pfSum;
for (i = 0; i < vPhi.size(); i++)
{
float* pfTemp = vPhi.at(i);
delete pfTemp;
}
vPhi.clear();
return fCapacity;
}
int main()
{
//转移矩阵
VEC_PFLOAT vTransMatrix;
int nCol,nLine;
cout<<"请输入信源符号个数:";
cin>>nLine;
cout<<"请输入信宿符号个数:";
cin>>nCol;
cout<<"请依次输入"<<<"行信道转移概率矩阵:(以空格隔开每个概率)\n";< /pre>
for (int i = 0; i < nLine; i++)
{
float *pfTemp = new float[nCol];
Label
float fSum = 0.0f;
cout<<"X"<<<":";
for (int j = 0; j < nCol - 1; j++)
{
cin>>pfTemp[j];
fSum += pfTemp[j];
}
if (1.0f - fSum < 0)
{
cout<<"转移概率和应该为1,请重新输入!\n";
goto Label1;
}
else
{
pfTemp[j] = 1.0f - fSum;
cout<<"信源符号 X"<<<"的转移概率分别为:";
for(int k = 0; k < nCol; k++)
cout<
cout<
}
vTransMatrix.push_back(pfTemp);
}
cout<<"信道容量为:"<< /pre>
for (int k = 0; k < vTransMatrix.size(); k++)
{
float* pfTemp = vTransMatrix.at(k);
delete pfTemp;
}
vTransMatrix.clear();
return 0;
}
using namespace std;
#define FLOAT_MINUS_PRECISION 0.00001
typedef vector<float*> VEC_PFLOAT;
//迭代计算信道容量,参数值为信源,信宿符号个数和信道转移概率矩阵,返回信道容量< /pre>
float GetCapacity(int nSourceSymbol,int nHostSymbol,const VEC_PFLOAT& vTransMatrix)
{
//信道容量初始化为最小值
float fCapacity = FLT_MIN;
//信源概率分布
float *pfSoureProb = new float[nSourceSymbol];
//初始化信源分布为均匀分布
int i;
for (i = 0; i < nSourceSymbol; i++)
{
pfSoureProb[i] = 1.0 / nSourceSymbol;
}
//初始化φ函数
VEC_PFLOAT vPhi;
for (i = 0; i < nSourceSymbol; i++)
{
float *pfTemp = new float[nHostSymbol];
vPhi.push_back(pfTemp);
}
//设置精度;
const float cfDelta = 0.02f;
float fPrecision;
//迭代计算
int j,k;
float *pfSum = new float[nSourceSymbol];
do
{
for (i = 0; i < nSourceSymbol; i++)
{
for (j = 0; j < nHostSymbol; j++)
{
//计算ΣPi*Pji
float fSum = 0.0f;
for (k = 0; k < nSourceSymbol; k++)
{
fSum += pfSoureProb[i] * vTransMatrix[k][i];
}
vPhi[i][j] = pfSoureProb[i] * vTransMatrix[j][i] / fSum;
}
}
float fSumDeno = 0.0f; //分母求和
for (i = 0; i < nSourceSymbol; i++)
{
float fSum = 0.0f;
for (j = 0; j < nHostSymbol; j++)
{
fSum += vTransMatrix[j][i] * logf(vPhi[i][j]);
}
pfSum[i] = expf(fSum);
fSumDeno += pfSum[i];
}
for (i = 0; i < nSourceSymbol; i++)
{
pfSoureProb[i] = pfSum[i] / fSumDeno;
}
//计算新一轮的容量
float fNewC = logf(fSumDeno);
//计算精度
fPrecision = fabs(fNewC - fCapacity) / fCapacity;
fCapacity = fNewC;
} while(fPrecision - cfDelta > 0.0f);
//释放临时资源

delete []pfSum;
for (i = 0; i < vPhi.size(); i++)
{
float* pfTemp = vPhi.at(i);
delete pfTemp;
}
vPhi.clear();
return fCapacity;
}
int main()
{
//转移矩阵
VEC_PFLOAT vTransMatrix;
int nCol,nLine;
cout<<"请输入信源符号个数:";
cin>>nLine;
cout<<"请输入信宿符号个数:";
cin>>nCol;
cout<<"请依次输入"<<<"行信道转移概率矩阵:(以空格隔开每个概率)\n";< /pre>
for (int i = 0; i < nLine; i++)
{
float *pfTemp = new float[nCol];
Label
float fSum = 0.0f;
cout<<"X"<<<":";
for (int j = 0; j < nCol - 1; j++)
{
cin>>pfTemp[j];
fSum += pfTemp[j];
}
if (1.0f - fSum < 0)
{
cout<<"转移概率和应该为1,请重新输入!\n";
goto Label1;
}
else
{
pfTemp[j] = 1.0f - fSum;
cout<<"信源符号 X"<<<"的转移概率分别为:";
for(int k = 0; k < nCol; k++)
cout<
cout<
}
vTransMatrix.push_back(pfTemp);
}
cout<<"信道容量为:"<< /pre>
for (int k = 0; k < vTransMatrix.size(); k++)
{
float* pfTemp = vTransMatrix.at(k);
delete pfTemp;
}
vTransMatrix.clear();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述