每个顶点的概率
Probability for each vertex
i有一个带有n个顶点和m边缘的图(n在1到15之间,m在1和n^2之间。该图是定向和加权的(具有该激发边缘的概率)。给您一个启动顶点和许多边缘。然后,该程序将计算每个顶点是末端顶点的概率。
检查输入:
3 3//顶点数量和边数
1 2 0.4//边缘NR.1从顶点1到2,概率为0.4
1 3 0.5//边缘NR.2从顶点1到3,概率为0.5
2 1 0.8//Edge Nr.3 ...
3//问题数
2 1//启动顶点,访问的边数
1 1
1 2
输出:
0.8 0.2 0.0//顶点1的概率beign beign beign the最后一个顶点为0.8,对于顶点2为0.2,对于顶点3,它是0.0
0.1 0.4 0.5
0.33 0.12 0.55
我在解决方案中使用了DFS,但是当访问的边缘数量最多可达10亿时,这太慢了...我一直在看DP,但我是不确定如何针对此特定问题实施它(即使是正确的解决方法)。因此,我希望你们中的一些人可以建议使用DFS和/或使用/实施DP的方法。
(我知道这可能有点混乱,我只在C 中编程一个月)
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
struct bird {
int colour;
float probability;
};
struct path {
int from;
int to;
};
vector <vector <bird>> birdChanges;
vector <int> layer;
vector <double> savedAnswers;
stack <path> nextBirds;
int fromBird;
//Self loop
void selfLoop(){
float totalOut = 0;
for (int i = 0; i < birdChanges.size(); i++) {
for (int j = 0; j < birdChanges[i].size(); j++) {
totalOut += birdChanges[i][j].probability;
}
if (totalOut < 1) {
bird a;
a.colour = i;
a.probability = 1 - totalOut;
birdChanges[i].push_back(a);
}
totalOut = 0;
}
}
double fillingUp(double momentarilyProbability, long long int numberOfBerries){
int layernumber=0;
while (layer[numberOfBerries - (1+layernumber)] == 0) {
layernumber++;
if (numberOfBerries == layernumber) {
break;
}
}
layernumber = layer.size() - layernumber;
path direction;
int b;
if (layernumber != 0) {
b= birdChanges[nextBirds.top().from][nextBirds.top().to].colour;//Usikker
}
else {
b = fromBird;
}
while (layer[numberOfBerries - 1] == 0) {
//int a = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
if (layernumber != 0) {
momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
//b = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
}
for (int i = 0; i < birdChanges[b].size(); i++) {
direction.from = b;
direction.to = i;
//cout << endl << "Stacking " << b << " " << birdChanges[b][i].colour;
nextBirds.push(direction);
layer[layernumber]++;
}
layernumber++;
b = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
}
//cout << "Returning" << endl;
return momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;;
}
//DFS
void depthFirstSearch(int fromBird, long long int numberOfBerries) {
//Stack for next birds (stack)
path a;
double momentarilyProbability = 1;//Momentarily probability (float)
momentarilyProbability=fillingUp(1, numberOfBerries);
//cout << "Back " << momentarilyProbability << endl;
//Previous probabilities (stack)
while (layer[0] != 0) {
//cout << "Entering" << endl;
while (layer[numberOfBerries - 1] != 0) {
savedAnswers[birdChanges[nextBirds.top().from][nextBirds.top().to].colour] += momentarilyProbability;
//cout << "Probability for " << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << " is " << momentarilyProbability << endl;
momentarilyProbability = momentarilyProbability / birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
nextBirds.pop();
layer[numberOfBerries - 1]--;
if (layer[numberOfBerries - 1] != 0) {
momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
}
}
if (layer[0] != 0) {
int k = 1;
while (layer[layer.size() - k]==0&&k+1<=layer.size()) {
//cout << "start" << endl;
momentarilyProbability = momentarilyProbability / birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
//cout << "Popping " << nextBirds.top().from << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << endl;
nextBirds.pop();
//cout << "k " << k << endl;
layer[numberOfBerries - 1 - k]--;
k++;
//cout << "end" << endl;
}
}
if (layer[0] != 0) {
//cout << 1 << endl;
//cout << "Filling up from " << nextBirds.top().from << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << endl;
momentarilyProbability = fillingUp(momentarilyProbability, numberOfBerries);
}
}
//Printing out
for (int i = 1; i < savedAnswers.size(); i++) {
cout << savedAnswers[i] << " ";
}
cout << endl;
}
int main() {
int numberOfColours;
int possibleColourchanges;
cin >> numberOfColours >> possibleColourchanges;
birdChanges.resize(numberOfColours+1);
int from, to;
float probability;
for (int i = 0; i < possibleColourchanges; i++) {
cin >> from >> to >> probability;
bird a;
a.colour = to;
a.probability = probability;
birdChanges[from].push_back(a);
}
selfLoop();
int numberOfQuestions;
cin >> numberOfQuestions;
long long int numberOfBerries;
for (int i = 0; i < numberOfQuestions; i++) {
cin >> fromBird >> numberOfBerries;
savedAnswers.assign(numberOfColours + 1, 0);
layer.resize(numberOfBerries, 0);
//DFS
depthFirstSearch(fromBird, numberOfBerries);
}
system("pause");
}
快速解释如何使用马尔可夫链的概念做到这一点:
Basic algorithm:
Input: starting configuration vector b of probabilities of
being in a vertex after 0 steps,
Matrix A that stores the probability weights,
in the scheme of an adjacency matrix
precision threshold epsilon
Output:
an ending configuration b_inf of probabilities after infinite steps
Pseudocode:
b_old = b
b_new = A*b
while(difference(b_old, b_new) > epsilon){
b_old = b_new
b_new = A*b_old
}
return b_new
在此算法中,我们本质上是计算概率矩阵的效力,并寻找何时变得稳定。
b是没有采取任何步骤后在顶点处的概率(因此,在您的情况下,除了开始顶点外,每个条目都是零,这是一个)
)a*b是一步之后的那些
a^2 * b是完成两个步骤后的a^n * b之后的
a^n * b。当a^n * b与a^n-1 * b几乎相同时,我们认为它不会再发生大的,它基本上与a^infinity * b
相同一个人可以用一些示例模拟该算法,例如一个带有很小概率的边缘的边缘,这将导致一个在无限步骤之后的概率1中导致一个子图中,但例如,从现实来看,它会起作用。
为了差异,欧几里得距离应该很好地工作,但是从本质上讲,您也可以使用最大或曼哈顿。
请注意,我提出了一种务实的观点,数学家将更多地详细介绍它的属性将收敛于epsilon的哪个值的速度。
您可能想将良好的库用于矩阵,例如eigen。
编辑:
阅读Jarod42的评论,我意识到您的步骤数量已得到。在这种情况下,只需使用a^step * b进行精确解决方案即可。使用一个好的库来快速计算效力。
- 如何循环打印顶点结构
- 如何根据单词在文本中出现的概率输出单词
- D3D11-将混合权重和索引传递到顶点着色器
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 如何将一半传递给顶点着色器?
- 在 DirectX 11 中从 GPU 读回顶点缓冲区(并获取顶点)
- QT QOpenGLWidget:如何在不使用数据块复制的情况下修改VBO中的单个顶点值?
- 使用 OpenGL 4.5 更改所选顶点的颜色
- Direct3D 11 - HLSL - 获取顶点索引 ID
- 创建异构顶点数据数组的可移植方法
- 使用 glvertex4i 传递网格面索引时的顶点着色器错误
- 无法从 cso 文件创建顶点着色器(从 fx 文件创建)
- OpenGL 相机移动程序顶点着色器问题
- 使用 std::list 存储顶点并使用 SFML 绘制它们
- 为什么顶点数组对象会导致错误?
- 从 CGAL 3D 网格生成中获取顶点坐标的 -6.27744e+66:mesh_implicit_sphere示例
- CNTK:如何在C++-API中获取类概率?
- 每个顶点的概率