Matrix 求最小顶点覆盖及Konig定理的实现
我正在尝试一步一步地实现Hunagrian算法(在^4上),如下所述:。我已经实现了查找最大匹配(而且很有效)。目前我正在测试算法的一部分,它使用了Konig定理(),但它似乎不能正常工作。。。为了找到最小顶点覆盖,我需要这个定理。我的代码逻辑有错误吗Matrix 求最小顶点覆盖及Konig定理的实现,matrix,graph,discrete-mathematics,hungarian-algorithm,Matrix,Graph,Discrete Mathematics,Hungarian Algorithm,我正在尝试一步一步地实现Hunagrian算法(在^4上),如下所述:。我已经实现了查找最大匹配(而且很有效)。目前我正在测试算法的一部分,它使用了Konig定理(),但它似乎不能正常工作。。。为了找到最小顶点覆盖,我需要这个定理。我的代码逻辑有错误吗 #include <iostream> #include <vector> using namespace std; typedef struct Edge { int weight; int dire
#include <iostream>
#include <vector>
using namespace std;
typedef struct Edge {
int weight;
int direction; // -1 - left, 0 - both, 1 - right
};
int N=0;
int* matchingLeft; // maximum matching
int* matchingRight;
bool* visited;
bool* visitedLeft;
bool* visitedRight;
Edge** matrix; // adj. matrix (cols are workers - right part of the graph, rows are tasks - left part of the graph)
bool dfs(int v)
{
if(visited[v]) return false; // already visited
visited[v]=true;
for(int i=0; i<N; i++)
if(matrix[v][i].weight==0 && (matchingRight[i]==-1 || dfs(matchingRight[i])))
{
matchingLeft[v]=i;
matchingRight[i]=v;
return true;
}
return false;
}
bool dfs_konig(int v, bool isLeft)
{
if(isLeft && visitedLeft[v]) return false; // already visited
if(!isLeft && visitedRight[v]) return false;
if(isLeft) visitedLeft[v]=true;
else visitedRight[v]=true;
for(int i=0; i<N; i++)
{
if(matrix[v][i].weight!=0) return false;
if(isLeft && matrix[v][i].direction==-1) return false;
if(!isLeft && matrix[v][i].direction==1) return false;
dfs_konig(i, !isLeft);
return true;
}
return false;
}
// Kuhn's maximum matching algortihm
int main()
{
cin >> N;
int counter=0;
matrix=new Edge*[N];
for(int i=0; i<N; i++)
{
matrix[i]=new Edge[N];
for(int j=0; j<N; j++)
{
cin >> matrix[i][j].weight;
matrix[i][j].direction = 0;
}
} // input
matchingLeft = new int[N];
matchingRight = new int[N];
visited = new bool[N];
std::fill( matchingLeft, matchingLeft+N, -1 );
std::fill( matchingRight, matchingRight+N, -1 );
for(int i=0; i<N; i++)
{
std::fill_n( visited, N, false );
if(dfs(i)) counter++; // graph is currently undirected
}
for(int i=0; i<N; i++)
{
if (matchingLeft[i] != -1){ cout << matchingLeft[i] << " "; }
}
cout << endl;
if(counter==N) cout << "COMPLETE!";
else
{
// konig theorem
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
if(matchingLeft[i]!=-1) {
matrix[i][j].direction=-1; // direct edges to left
}
else matrix[i][j].direction=1; // direct edges to right
}
}
visitedLeft = new bool[N];
visitedRight = new bool[N];
std::fill( visitedLeft, visitedLeft+N, false );
std::fill( visitedRight, visitedRight+N, false);
for(int i=0; i<N; i++)
{
if(matchingLeft[i]==-1) dfs_konig(i, true); // if left vertex isn't in maximum matching, then run dfs from it
}
for(int i=0; i<N; i++)
{
if(!visitedLeft[i]) cout << i << " ";
}
cout << endl;
for(int i=0; i<N; i++)
{
if(visitedRight[i]) cout << i << " ";
}
cout << endl;
delete visitedLeft;
delete visitedRight;
}
delete matchingLeft;
delete matchingRight;
delete visited;
for(int i=0; i<N; i++)
{
delete matrix[i];
}
delete matrix;
system("pause");
return 0;
}
#包括
#包括
使用名称空间std;
typedef结构边缘{
整数权重;
int方向;/-1-左,0-双,1-右
};
int N=0;
int*matchingLeft;//最大匹配
int*匹配权;
布尔*访问;
布尔*访问左侧;
布尔*访问权;
边**矩阵;//形容词。矩阵(列是工作者-图的右侧部分,行是任务-图的左侧部分)
布尔dfs(int v)
{
if(visted[v])返回false;//已访问
访问[v]=正确;
对于(int i=0;i