我认为问题在于int w1变量。我无法直接在列表中引用它,因此我无法说明该特定女性是否比当前男性(m1)更喜欢该男性(m1)。
我尝试了许多不同的方法来解决此问题,但是所有这些方法都会导致输出相同的结果,没有进行匹配,而且每个人都保持单身状态,我无法弄清楚哪里出了问题。
public static void makeMatches(List<Person> list1, List<Person> list2) {
// set each person to be free
for (Person m : list1) {
m.erasePartner();
}
for (Person w: list2) {
w.erasePartner();
}
for (Person m : list1) {
for (Person w : list2) {
// find man with nonempty preference list that is free
while (m.hasChoices() && !m.hasPartner()) {
// first woman on man's list
int w1 = m.getFirstChoice();
for (Person m1 : list1) {
// if chosen woman is free, set her to be man's partner
if (!w.hasPartner()) {m.setPartner(w1);
// if chosen woman has partner, set her to be free and engage her and man
} else if (w.hasPartner()) {
if (w.getPartnerRank() < w.getChoices().indexOf(m)) {
w.erasePartner();
m.setPartner(w1);
}
}
}
}
}
}
}
import java.util.*;
public class Person {
public static final int NOBODY = -1;
private String name;
private List<Integer> preferences;
private List<Integer> oldPreferences;
private int partner;
public Person(String name) {
this.name = name;
preferences = new ArrayList<Integer>();
oldPreferences = new ArrayList<Integer>();
erasePartner();
}
public void erasePartner() {
partner = NOBODY;
}
public boolean hasPartner() {
return partner != NOBODY;
}
public int getPartner() {
return partner;
}
public void setPartner(int partner) {
this.partner = partner;
}
public String getName() {
return name;
}
public boolean hasChoices() {
return !preferences.isEmpty();
}
public int getFirstChoice() {
return preferences.get(0);
}
public void addChoice(int person) {
preferences.add(person);
oldPreferences.add(person);
}
public List<Integer> getChoices() {
return preferences;
}
public int getPartnerRank() {
return oldPreferences.indexOf(partner) + 1;
}
}
测试文件: 男人0:3 0 1 2 男人1:1 2 0 3 男人2:1 3 2 0 男人3:2 0 3 1 结束 女人0:3 0 2 1 女人1:0 2 1 3 女人2:0 1 2 3 女人3:3 0 2 1 结束
输出: 男士火柴
男人0-没有人 男人1-没有人 男人2-没有人 男人3-没有人 均值选择= NaN
女性比赛
女人0-没有人 女人1-没有人 女人2-没有人 女人3-没有人 平均选择= NaN 结果应使用Gale-Shapley算法将每个男人与一个女人配对。
答案 0 :(得分:0)
这里有几个问题。首先,我不确定为什么您在makeMatches
中有这个double for循环结构。 Gale-Shapley的条件是要迭代列出的人员列表,只要至少有一个仍未订婚但仍然有人提议但尚未提议的人。因此,我将删除double for循环并保留while循环,但改为更改内部条件以调用方法,也许将其称为stillNotEngaged
,该方法返回未参与且仍然处于活动状态的男性列表中某人的索引有选择权,如果他们全都参与或没有其他选择,则返回-1或NOBODY
。
public static void makeMatches(List<Person> list1, List<Person> list2) {
// code from before that set each partner free
int m1 = stillNotEngaged(list1, list2);
while (m1 != -1) { // at least one not engaged or has choices
// to be filled in later in this answer...
m1 = stillNotEngaged(list1, list2);
}
}
public static int stillNotEngaged(List<Person> men, List<Person> women) {
for (int i = 0; i < men.size(); i++) {
if (!men.get(i).hasPartner() && men.get(i).hasChoices()) {
return i;
}
}
return NOBODY;
}
然后,确保将两者的伴侣都设置为男人和女人。在您只设置男人的伴侣之前。而且,如果确实发生了离婚,不仅要清除女性的伴侣,还要清除两者。或者,为使离婚更容易,只需清除旧丈夫的伴侣,然后设置新的夫妻伴侣即可。最后,我不太确定为什么要使用oldPreferences
,也不确定为什么要在getPartnerRank
方法中将1加到排名,为什么不只使用{{1 }},
preferences
还要记住的另一件事是,当一个男人求婚时,您应该将该女人从该男人的偏好中删除,否则循环将是无限的。加里-沙普利(Gary-Shapley)最多只能让男人向每个女人求婚,所以也许考虑像这样制作一种叫做public int getPartnerRank() {
return preferences.indexOf(partner);
}
的方法,
removeChoice
总而言之,如果您实施了我刚刚提到的新更改,则public void removeChoice(int w) {
preferences.remove(preferences.indexOf(w));
}
方法现在应如下所示,
makeMatches