Несколько вопросов здесь.Во-первых, я не уверен, почему у вас есть двойная структура цикла в makeMatches
.Условие Гейл-Шепли состоит в том, чтобы перебирать список мужчин, пока существует хотя бы один человек, который все еще не помолвлен, но у него еще есть кто-то, кто может предложить то, что он еще не сделал.Поэтому я удалил бы двойной цикл 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
и почему вы добавляете 1 к рангу в методе getPartnerRank
, почему бы просто не использовать индекс партнера в preferences
, как это так,
public int getPartnerRank() {
return preferences.indexOf(partner);
}
Еще одна вещь, которую следует иметь в виду, заключается в том, что, когда мужчина предлагает, вы должны исключить эту женщину из предпочтений мужчины, иначе цикл будет бесконечным.Гэри-Шепли предлагает мужчинам предлагать каждой женщине не более одного раза, поэтому, возможно, стоит подумать о создании метода под названием removeChoice
, например,
public void removeChoice(int w) {
preferences.remove(preferences.indexOf(w));
}
В общем, если вы внедрите новые изменения, которые я только что упомянул, ваш makeMatches
метод теперь должен выглядеть так:
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();
}
int m1 = stillNotEngaged(list1, list2);
while (m1 != -1) { // at least one not engaged and has choices
int w1 = m.getFirstChoice();
Person m = list1.get(m1);
Person w = list2.get(w1);
if (!w.hasPartner()) {
m.setPartner(w1);
w.setPartner(m1);
}
// if chosen woman has partner, set her to be free and engage her and man
else if (w.hasPartner()) {
// assuming preferences are in descending order, so index 0 is the first priority choice
if (w.getPartnerRank() > w.getChoices().indexOf(m1)) {
list1.get(w.getPartner()).erasePartner();
w.setPartner(m1);
m.setPartner(w1);
}
}
m.removeChoice(w1);
m1 = stillNotEngaged(list1, list2);
}
}