这是个编程问题,程序已编好,特向高手请教
有n个男孩m1,m2,…,mn与n个女孩w1,w2,wn。每一个男孩mi都依照喜爱这n个女孩的程度列成一张表,最喜欢的女孩排在第1位,最不喜爱的女孩排在第n位;同样地,每一个女孩wi也依照她喜爱n个男孩的程度列成一张表。请写一个程序,把每一个男孩与 女孩的喜爱表格读入,并且把男孩与女孩一一配对,使得:如果mp与wq是一对的话,那么 第一:对mp的喜爱表格中排在wq之前的女孩而言,她的伴侣在她的表格中一定排在 mp之 前;第二:对wq的喜爱表格中排在mp之前的男孩而言,他的伴侣在他的表格中一定排在wq之前。这就是稳定伴侣(Stable Marriage)问题。【说明】
这个问题恐怕要多说一些才能讲得明白。先讲不稳定(Unstable)的情况;如果m的女伴记成PM(m),而w的男伴记成PW(w)。如果有一对男孩与女孩m与w,他们不是伴侣(用上面的记号,m的伴侣是PM(m),w的伴侣是PW(w)),但m比较中意w而不是PM(m),则同时w比较中意m而不是PW(w)的时候,m与w就一定心不甘情不愿了。例如,如果A与B是男孩,X与Y是女孩,A比较中意X,B比较中意Y,A与Y、B与X结伴,那么 A 与 Y 心目中的情人都不是对方,B 与 X 亦然,这就是不稳定的状况。稳定伴侣的问题,就是要在喜爱的表格中配出最合适、稳定的伴侣,而不是“乔太守乱点鸳鸯谱”制造对对怨偶。
看一个完整的例子。假设男孩与女孩都用编号 1,2,3,4,其喜爱表格如下。
男 孩 女 孩
1: 2 4 1 3 1: 2 1 4 3
2: 3 1 4 2 2: 4 3 1 2
3: 2 3 1 4 3: 1 4 3 2
4: 4 1 3 2 4: 2 1 4 3
表格中指出,男孩1最中意的女孩是 2,其次是4与1,最后是3;对于女孩3而言,她最中意 1,其次是4与3,最后是2,对于这两份喜欢表格而言,稳定伴侣是如下。
男 孩 女 孩
1 4
2 3
3 2
4 1
第1号男孩与第4号女孩配对,他们是不是怨偶?在第1号男孩喜欢表格中,排在第4号女孩之前的是第2号;再看第4号女孩,在她的喜爱表格中排在1之前的是第2号男孩,于是都符合了稳定条件。用同样的方法可以查证其他的3对伴侣。在编写程序时,可以用男孩为主,对女孩求婚,而由女孩由她的喜爱表格来决定接受还是不接受;如果可以接受,就不妨先接受,等到有更中意的男孩求婚了,就中止上一个约定,另结新欢(不是现实世界,不必太拘泥)。数据证明,一定可以找出稳定伴侣的结果的。在常见的问题中,计算机择友就是一个类似的问题,但要求却比较松些,因为男友双 方不必列出对“所有”对象的喜爱程度,而且也有可能出现喜爱程度相同的情形,当然解题 的方法就复杂了。
以上是编程问题,下面是已编好的程序,求高手指点迷津,有什么可以改进或是不足的地方。还有就是,编程要求上要我写出报告提纲:框架设计(包括算法设计、程序流程图、各模块之间关系等)、详细设计(详细 说明关键部分代码)、实验结果(程序测试结果)、调试(说明开发过程中遇到的 BUG 及原因, 出现的问题这一点尤其重要,请同学们重视)、总结、最后附程序完整代码。 这些我不是太懂,也请高手指教一番。谢谢!
/*-------主函数-----*/
/*
首先输入情侣对数,根据个数然后初始化所有的人类
然后先进行一轮汉子表白
再无限循环寻找被抛弃的汉子直到所有人配对成功
最后打印出配对结果
*/
void main(){
srand((unsigned)time( NULL ));
printf("请输入有多少对情侣:");
scanf("%d",&mateNumber);
Girl* girls=(Girl *)malloc(GirlSize*mateNumber);
Boy* boys=(Boy *)malloc(BoySize*mateNumber);
for(int index=0;index<mateNumber;index++){
initializeGirl(&girls[index],index);
initializeBoy(&boys[index],index);
}
for(int index=0;index<mateNumber;index++)
boyFindLove(girls,boys,index,boys[index].LikeRank);
int whoBachelor=findbachelor(boys);
while(whoBachelor!=-1){
boyFindLove(girls,boys,whoBachelor,boys[whoBachelor].LikeRank);
whoBachelor=findbachelor(boys);
};
printMate(boys);
system("pause");
}
/*-----程序函数----*/
void initializeGirl(Girl* girl,int name)
{
girl->Name=name;
girl->Mate=-1;
girl->LikeRank=(int *)malloc(sizeof(int)*mateNumber);
for(int i=0;i<mateNumber;i++)
{
girl->LikeRank[i]=i;
}
shuffleArray(girl->LikeRank,mateNumber);
girlShowLikeRank(girl->Name,girl->LikeRank);
}
void initializeBoy(Boy* boy,int name)
{
boy->Name=name;
boy->Mate=-1;
boy->LikeRank=(int *)malloc(sizeof(int)*mateNumber);
for(int i=0;i<mateNumber;i++)
{
boy->LikeRank[i]=i;
}
shuffleArray(boy->LikeRank,mateNumber);
boyShowLikeRank(boy->Name,boy->LikeRank);
}
void girlShowLikeRank(int name,int* LikeRank)
{
printf("我是姑娘%d,以下是我的喜欢排行榜:\n",name);
for(int index=0;index<mateNumber;index++)
printf("第%d位:%d\n",index,LikeRank[index]);
}
void boyShowLikeRank(int name,int* LikeRank)
{
printf("我是汉子%d,以下是我的喜欢排行榜:\n",name);
for(int index=0;index<mateNumber;index++)
printf("第%d位:%d\n",index,LikeRank[index]);
}
void boyFindLove(Girl* girls,Boy* boys,int boyName,int* LikeRank)
{
for(int index=0;index<mateNumber;index++)
if(girlSayYes(LikeRank[index],boyName,girls,boys))
{
boys[boyName].Mate=LikeRank[index];
break;
}
}
bool girlSayYes(int girlName,int boyName,Girl* girls,Boy* boys)
{
if(girls[girlName].Mate==-1){
printf("我是妹子%d,%d向我求爱,我没有对象于是同意\n",girlName,boyName);
girls[girlName].Mate=boyName;
return true;
}
else if(findSequenceNumber(girls[girlName].LikeRank,girls[girlName].Mate)>
findSequenceNumber(girls[girlName].LikeRank,boyName))
{
printf("我是妹子%d,%d向我求爱,我抛弃原配%d\n",girlName,boyName,girls[girlName].Mate);
boys[girls[girlName].Mate].Mate=-1; //抛弃原配
girls[girlName].Mate=boyName;
return true;
}
else {
printf("我是妹子%d,%d向我求爱,我更喜欢原配%d\n",girlName,boyName,girls[girlName].Mate);
return false;}
}
/*
寻找仍然单身的汉子
找到返回名字,没找到返回-1;
*/
int findbachelor(Boy* boys)
{
for(int index=0;index<mateNumber;index++)
{
if(boys[index].Mate==-1) return index;
}
return -1;
}
void printMate(Boy* boys)
{
for(int index=0;index<mateNumber;index++)
printf("我是汉子%d,我的稳定妹子是%d\n",index,boys[index].Mate);
}
/*---工具函数--*/
int findSequenceNumber(int* LikeRank,int boyName)
{
for(int index=0;index<mateNumber;index++)
if(LikeRank[index]==boyName) return index;
}
void shuffleArray(int array[],int arraySize)
{
int i,j,T=100,tmp;
while(T--)
{
i=rand()%arraySize;
j=rand()%arraySize;
tmp=array[i];
array[i]=array[j];
array[j]=tmp;
}
}