我有一个C程序,据我所知,应该按预期工作。它试图实现Gale-Shapley稳定婚姻算法。在我的程序中,你给予程序一个3x 3或4x 4矩阵的文件。当程序执行时,它会提示一个文件名,读取文件,并将结果显示为n × n矩阵。示例矩阵如下:
3
2 1 3
2 3 1
3 2 2
2 3 1
3 1 2
2 3 1
结果矩阵如下所示:
还有一个4x 4矩阵示例:
4
1 2 3 4
1 4 3 2
2 1 3 4
4 2 3 1
4 3 1 2
2 4 1 3
4 1 3 2
3 2 1 4
现在,我以为代码工作正常,但是函数中似乎有问题。代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 10
int n;
int pref_m[MAX_N][MAX_N], pref_w[MAX_N][MAX_N];
int match[MAX_N], engaged[MAX_N];
void stable_marriage()
{
int i, m, w, m1;
for (i = 0; i < n; i++)
engaged[i] = -1; // initialize engaged[] to -1 to indicate unengaged persons
while (1) {
m = -1;
for (i = 0; i < n; i++) {
if (engaged[i] == -1) { // use -1 to indicate unengaged persons
m = i;
break;
}
}
if (m == -1) {
break;
}
printf("Made it");
for (i = 0; i < n && match[m] == -1; i++) { // use -1 to indicate unassigned persons
w = pref_m[m][i];
if (engaged[w] == -1) {
engaged[w] = m;
match[m] = w;
} else {
m1 = engaged[w];
if (pref_w[w][m] < pref_w[w][m1]) {
engaged[m1] = -1; // unengage m1 before engaging m
engaged[w] = m;
match[m] = w;
match[m1] = -1; // unassign m1
}
// add tie-breaking logic here if desired
}
}
}
}
int main()
{
char filename[256];
printf("Enter file name: ");
scanf("%s", filename);
FILE *file = fopen(filename, "r");
fscanf(file, "%d", &n);
printf("n = %d\n", n);
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
fscanf(file, "%d", &pref_m[i][j]);
printf("%d ", pref_m[i][j]);
pref_m[i][j]--;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
fscanf(file, "%d", &pref_w[i][j]);
printf("%d ", pref_w[i][j]);
pref_w[i][j]--;
}
}
fclose(file);
stable_marriage();
printf("Solution:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (match[i] == j) {
printf("1 ");
} else {
printf("0 ");
}
}
printf("\n");
}
return 0;
}
在第二个while
循环之前的函数中似乎有一个无限循环。Made It
print语句永远运行,但当我在for
循环之后有print语句时,它不会到达那里。有什么帮助吗?
1条答案
按热度按时间drnojrws1#
match
数组从未像engaged数组那样初始化为-1。因为在print语句之后的for循环中的一个条件是检查match[m] == -1
并索引到未初始化的数组会导致undefined behavior
。这导致循环永远不会进入,因为其中一个and
条件为false。初始化
match
数组的解决方案:此外,match[m]值在第一次迭代后立即设置为0。这会锁定循环并阻止您进入它,从而创建另一个无限循环。解决方案是使用标志来检查匹配,而不是像这样索引检查: