1

昨天我在算法课上做功课,Gale-Shapley 算法的一个实现,它是一种解决相同数量的男性和女性之间的匹配问题的算法,他们有自己的匹配优先级。然后在编码之后,我发现它的功能并不好,因为输入不同,但我就是不知道为什么,也许它有什么。与内存溢出有关。如果有人能指出我的错误,那将对我有很大帮助。十分感谢!这是我教科书中的代码和伪代码:

#include <iostream>
using namespace std;
bool isOneFree(int n,bool*P)    // test if there's at least one man Free.
{
    for(int i=0;i<n;i++)
    {
        if(*(P+i)==true)    return true;
    }
    return false;
}

int* Matching(int n,int**MP,int**WP) // numbers, priority lists of males and females.
{
    bool isManFree[n],isWomanFree[n],isManProposed[n][n];   // to represent matching states.
    int match[n];   // index-value(man-woman) pair

    for(int i=0;i<n;i++)    // initialize values.
    {
        isManFree[i]=true;
        isWomanFree[i]=true;
        for(int j=0;j<n;j++){   isManProposed[i][j]=false;    }
        match[i]=-1;
    }

    while(isOneFree(n,isManFree))   // all matching completed if it returns false.
    {
        int indexM;
        for(int i=0;i<n;i++)
        {
            if(isManFree[i]==true)  { indexM=i; break; }    // we'll try matching this guy with a girl!
        }

        int indexWo;
        for(int i=0;i<n;i++)
        {
            int w=MP[indexM][i];
            if(isManProposed[indexM][w]==false)  { indexWo=w;   break;}  // current priority
        }
        isManProposed[indexM][indexWo]=true;

        if(isWomanFree[indexWo])
        {
            isManFree[indexM]=false;
            isWomanFree[indexWo]=false;
            match[indexM]=indexWo; // they're engaged!
        }
        else    // she's engaged to someone already.
        {
            int indexRival; // find the competitor's index.
            for(int i=0;i<n;i++)
            {
                if(match[i]==indexWo){ indexRival=i;    break; }
            }

            int pM,pRival;
            for(int i=0;i<n;i++)
            {
                if(WP[indexWo][i]==indexM)  pM=i;
                if(WP[indexWo][i]==indexRival)  pRival=i;
            }
            if(pM<pRival)   // the girl's decision
            {
                isManFree[indexM]=false;
                isManFree[indexRival]=true;
                isWomanFree[indexWo]=false;
                match[indexM]=indexWo;  // change the match
            }
        }
    }
    return match;
}

int main()
{
    int n;
    cin>>n;
    int**MP,**WP;
    MP=new int*[n];
    for(int i=0;i<n;i++)    // a lot of inputs
    {
        MP[i]=new int[n];
        for(int j=0;j<n;j++)
        {
            cin>>MP[i][j];
        }
    }
    WP=new int*[n];
    for(int i=0;i<n;i++)
    {
        WP[i]=new int[n];
        for(int j=0;j<n;j++)
        {
            cin>>WP[i][j];
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            MP[i][j]--; // inputs are 1~n, get indexes 0~n-1
            WP[i][j]--;
        }
    }

    int*match=Matching(n,MP,WP);
    for(int i=0;i<n;i++)
    {
        cout<<*(match+i)+1<<" ";    // output: matching result
    }
    return 0;
}

伪代码:

Initially all m belongs to M and w belongs to W are free
While there is a man m who is free and hasn’t proposed to every woman
    Choose such a man m
    Let w be the highest-ranked woman in m’s preference list to whom m has not yet proposed
    If w is free then
        (m, w) become engaged
    Else w is currently engaged to m’
        If w prefers m’ to m then
            m remains free
        Else w prefers m to m’
            (m,w) become engaged
            m’becomes free
        Endif
    Endif
Endwhile
Return the set S of engaged pairs

这是示例输入和输出:
5
2 1 4 5 3
4 2 1 3 5
2 5 3 4 1
1 4 3 2 5
2 4 1 5 3
5 1 2 4 3
3 2 4 1 5
2 3 4 5 1
1 5 4 3 2
4 2 5 3 1

1 3 2 5 4

4

1 回答 1

4

快速浏览一下您的代码,我看到的一个问题是函数

int* Matching(int n,int**MP,int**WP)

正在返回一个局部变量的地址,这是一个很大的禁忌。

我将代码更改如下:

int* Matching(int n,int**MP,int**WP) // numbers, priority lists of males and females.
{
    bool isManFree[n],isWomanFree[n],isManProposed[n][n];   // to represent matching states.
    int *match = new int[n];   // index-value(man-woman) pair

完成后释放它:

int*match=Matching(n,MP,WP);
for(int i=0;i<n;i++)
{
    cout<<*(match+i)+1<<" ";    // output: matching result
}
delete [] match;
return 0;

你也应该释放内存

int **MP, 和int **WP

我相信这是问题所在,它的发生是因为局部变量的内存int match[n];仅在分配它的函数内部有效。

如果您有兴趣,对此有更“科学”的解释。

于 2012-10-12T12:45:43.340 回答