Algorithm 将递归算法转换为迭代算法
我正在尝试将下面的算法实现为一个迭代算法,但我不能正确地实现它。谁能帮我一下吗。这是一个二分匹配算法,我在将bpm函数转换为迭代函数时遇到了麻烦Algorithm 将递归算法转换为迭代算法,algorithm,recursion,graph,matching,bipartite,Algorithm,Recursion,Graph,Matching,Bipartite,我正在尝试将下面的算法实现为一个迭代算法,但我不能正确地实现它。谁能帮我一下吗。这是一个二分匹配算法,我在将bpm函数转换为迭代函数时遇到了麻烦 // A DFS based recursive function that returns true if a // matching for vertex u is possible bool bpm(bool bpGraph[M][N], int u, bool seen[], int matchR[]) { // Try every
// A DFS based recursive function that returns true if a
// matching for vertex u is possible
bool bpm(bool bpGraph[M][N], int u, bool seen[], int matchR[])
{
// Try every job one by one
for (int v = 0; v < N; v++)
{
// If applicant u is interested in job v and v is
// not visited
if (bpGraph[u][v] && !seen[v])
{
seen[v] = true; // Mark v as visited
// If job 'v' is not assigned to an applicant OR
// previously assigned applicant for job v (which is matchR[v])
// has an alternate job available.
// Since v is marked as visited in the above line, matchR[v]
// in the following recursive call will not get job 'v' again
if (matchR[v] < 0 || bpm(bpGraph, matchR[v], seen, matchR))
{
matchR[v] = u;
return true;
}
}
}
return false;
}
// Returns maximum number of matching from M to N
int maxBPM(bool bpGraph[M][N])
{
// An array to keep track of the applicants assigned to
// jobs. The value of matchR[i] is the applicant number
// assigned to job i, the value -1 indicates nobody is
// assigned.
int matchR[N];
// Initially all jobs are available
memset(matchR, -1, sizeof(matchR));
int result = 0; // Count of jobs assigned to applicants
for (int u = 0; u < M; u++)
{
// Mark all jobs as not seen for next applicant.
bool seen[N];
memset(seen, 0, sizeof(seen));
// Find if the applicant 'u' can get a job
if (bpm(bpGraph, u, seen, matchR))
result++;
}
return result;
}
//基于DFS的递归函数,如果
//可以匹配顶点u
布尔bpm(布尔bpGraph[M][N],int u,布尔seen[],int matchR[]
{
//一个接一个地尝试每项工作
对于(int v=0;v
诀窍在于你需要一堆动作。因此,当您进入循环时,首先将递归调用之后要执行的所有操作添加到堆栈中,然后将递归调用放入。他们将以相反的顺序执行,当你做下半场时,你知道上半场发生了什么
在类似这样的伪代码中
function somethingRecursive(stuff):
beforeRecursive(stuff)
somethingRecursive(whatever)
afterRecursive(stuff)
变成这样:
while actions:
action = actions.pop()
if action.unwind:
afterRecursive(action.stuff)
else:
beforeRecursive(action.stuff)
actions.push(new Action(unwind, stuff))
actions.push(new Action(recurse, whatever))
诀窍是你需要一堆动作。因此,当您进入循环时,首先将递归调用之后要执行的所有操作添加到堆栈中,然后将递归调用放入。他们将以相反的顺序执行,当你做下半场时,你知道上半场发生了什么 在类似这样的伪代码中
function somethingRecursive(stuff):
beforeRecursive(stuff)
somethingRecursive(whatever)
afterRecursive(stuff)
变成这样:
while actions:
action = actions.pop()
if action.unwind:
afterRecursive(action.stuff)
else:
beforeRecursive(action.stuff)
actions.push(new Action(unwind, stuff))
actions.push(new Action(recurse, whatever))
我终于让它工作了
typedef struct
{
int uParam;
int vLocal;
int location;
}bpmState;
bool bpm_nr(bool bpGraph[M][N], int uParam, int matchR[])
{
bool seen[N];
memset(seen, 0, sizeof(seen));
stack<bpmState> states;
states.push({ uParam, 0, 1 });
bool rvalue = false;
while (!states.empty())
{
auto state = states.top();
states.pop();
switch (state.location)
{
case 1:
for (int v = state.vLocal, u = state.uParam; v < N; v++)
{
if (bpGraph[u][v] && !seen[v])
{
seen[v] = true;
if (matchR[v] < 0)
{
matchR[v] = u;
rvalue = true;
}
else
{
states.push({ u, v, 2 });
states.push({ matchR[v], 0, 1 });
}
break;
}
}
break;
case 2:
if (rvalue)
{
matchR[state.vLocal] = state.uParam;
rvalue = true;
}
else
{
states.push({ state.uParam, state.vLocal + 1, 1 });
}
break;
}
}
return rvalue;
}
typedef结构
{
int-uParam;
内部局部;
int定位;
}BPM状态;
bool bpm_nr(bool bpGraph[M][N],int-uParam,int-matchR[]
{
bool-seen[N];
memset(seen,0,sizeof(seen));
堆栈状态;
push({uParam,0,1});
布尔右值=假;
而(!states.empty())
{
自动状态=states.top();
states.pop();
开关(状态位置)
{
案例1:
for(int v=state.vLocal,u=state.uParam;v
我终于让它工作了
typedef struct
{
int uParam;
int vLocal;
int location;
}bpmState;
bool bpm_nr(bool bpGraph[M][N], int uParam, int matchR[])
{
bool seen[N];
memset(seen, 0, sizeof(seen));
stack<bpmState> states;
states.push({ uParam, 0, 1 });
bool rvalue = false;
while (!states.empty())
{
auto state = states.top();
states.pop();
switch (state.location)
{
case 1:
for (int v = state.vLocal, u = state.uParam; v < N; v++)
{
if (bpGraph[u][v] && !seen[v])
{
seen[v] = true;
if (matchR[v] < 0)
{
matchR[v] = u;
rvalue = true;
}
else
{
states.push({ u, v, 2 });
states.push({ matchR[v], 0, 1 });
}
break;
}
}
break;
case 2:
if (rvalue)
{
matchR[state.vLocal] = state.uParam;
rvalue = true;
}
else
{
states.push({ state.uParam, state.vLocal + 1, 1 });
}
break;
}
}
return rvalue;
}
typedef结构
{
int-uParam;
内部局部;
int定位;
}BPM状态;
bool bpm_nr(bool bpGraph[M][N],int-uParam,int-matchR[]
{
bool-seen[N];
memset(seen,0,sizeof(seen));
堆栈状态;
push({uParam,0,1});
布尔右值=假;
而(!states.empty())
{
自动状态=states.top();
states.pop();
开关(状态位置)
{
案例1:
for(int v=state.vLocal,u=state.uParam;v
这应该是一个使用堆栈从递归DFS到迭代DFS的简单转换。这看起来像是一个重复。如果您认为不是,请详细说明原因,否则我将以dupe结束。它的不同之处在于我们处理当前调用的方式将取决于其余递归dfs调用的输出。迭代算法处理当前节点并移动到下一个迭代