Points, total availability (bachelor + master) and type of project class must be considered when sorting a list of Pair representing matches.

This commit is contained in:
Tom Vahlman 2012-02-25 21:47:03 +01:00
parent 09dbafb5b6
commit 9ce03fcaa1
2 changed files with 77 additions and 10 deletions
src
main/java/se/su/dsv/scipro/match
test/java/se/su/dsv/scipro/match

@ -20,7 +20,14 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
private Logger logger = Logger.getLogger(GreedyMatchingAlgorithm.class);
private Weights weights;
/**
* Match project ideas with supervisors (based on availability) and returns the best match.
* @param supervisorAvailability a list of the Availability instances
* @param unmatchedProjectIdeas a list of unmatched project ideas
* @param weights the weights that is used when counting points
* @return Result
*/
@Override
public Result match(List<Availability> supervisorAvailability, List<ProjectIdea> unmatchedProjectIdeas, Weights weights) {
this.weights = weights;
@ -30,14 +37,17 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
while(!unmatchedProjectIdeas.isEmpty()) {
pairList.clear();
matchProjectIdeas(unmatchedProjectIdeas, supervisorAvailability, pairList);
Collections.sort(pairList);
if(!pairList.isEmpty()) {
Collections.sort(pairList);
calculateTotalAvailability(pairList);
Pair foundPair = pairList.get(0);
for(Availability availability : supervisorAvailability) {
if(availability.getSupervisor().equals(foundPair.getMatch().getSupervisor())) {
if(availability.getSupervisor().equals(foundPair.getMatch().getSupervisor()) &&
availability.getProjectClass().equals(foundPair.getAvailability().getProjectClass())) {
if(availability.getNumCapable() > availability.getNumMatched()) {
availability.setNumMatched(availability.getNumMatched() + 1);
matchList.add(foundPair.getMatch());
matchList.add(foundPair.getMatch());
}
}
}
@ -178,7 +188,7 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
&& supervisor.equals(projectIdea.getPreferredSupervisor())) {
points += weights.getPreferredSupervisorPoints();
}
for (Keyword projectIdeaKeyword : projectIdea.getKeywords().getAll()) {
for (Keyword supervisorKeyword : supervisor.getKeywords().getFiltered(projectIdeaKeyword.getType())) {
if (projectIdeaKeyword.equals(supervisorKeyword) && !projectIdeaKeyword.isDeleted() && !supervisorKeyword.isDeleted()) {
@ -190,10 +200,39 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
match.setPoints(points);
return match;
}
/**
* Calculates total availability for each supervisor, i.e. the Availability#getAvailability (int) for master
* is added to Availability#getAvailability (int) for bachelor for each supervisor, this total availability is considered when
* matching project ideas to supervisors
* @param pairList all the matches that is produced, represented as instances of the class Pair
* @return
*/
private void calculateTotalAvailability(List<Pair> pairList) {
for(Pair ourMatch : pairList) {
for(Pair pair : pairList) {
if(ourMatch.getTotalAvailability() == 0 &&
ourMatch.getAvailability().getSupervisor().equals(pair.getAvailability().getSupervisor()) &&
!ourMatch.getAvailability().getProjectClass().equals(pair.getAvailability().getProjectClass())) {
int totalAvailability = ourMatch.getAvailability().getAvailability() + pair.getAvailability().getAvailability();
ourMatch.setTotalAvailability(totalAvailability);
pair.setTotalAvailability(totalAvailability);
break;
}
}
}
for(Pair ourMatch : pairList) { // we must set total availability for supervisors that only can handle one type of project class, i.e. master or bachelor
if(ourMatch.getTotalAvailability() == 0) {
ourMatch.setTotalAvailability(ourMatch.getAvailability().getAvailability());
}
}
}
private class Pair implements Comparable<Pair> {
private Match match;
private Availability availability;
private int totalAvailability;
public Pair(Match match, Availability availability
) {
@ -209,14 +248,42 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
return availability;
}
public int getTotalAvailability() {
return totalAvailability;
}
public void setTotalAvailability(int totalAvailability) {
this.totalAvailability = totalAvailability;
}
/**
* Is used to sort the Pairs in an order where the Pair at the top of the list will be chosen.
* @param otherPair the pair we should compare with
* @return int determines if one Pair is more "important" than another Pair.
*/
@Override
public int compareTo(Pair otherPair) {
if(match.getPoints() > otherPair.getMatch().getPoints()) {
return -1;
} else if(otherPair.getMatch().getPoints() > match.getPoints()) {
return 1;
} else {
return availability.compareTo(otherPair.getAvailability());
} else { // if the points are the same
if(totalAvailability > otherPair.getTotalAvailability()) { // does we have more "slots" than the other Pair
return -1;
} else if(otherPair.getTotalAvailability() > totalAvailability) {
return 1;
} else { // the points and the slots are equal, we must now sort on Project Class because a master supervisor can supervise
// both a master project idea and a bachelor project idea, the "best" match however is if a master supervisor supervises a master project idea...
if(match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
!otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
return -1;
} else if(!match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
return 1;
} else { // the supervisor can only one type of project class
return 0;
}
}
}
}

@ -98,9 +98,9 @@ public class TestGreedyMatchingAlgorithm {
private void createWeights() {
weights = new Weights();
weights.setKeywordPoints(3); // "Word" (including "Unit"??)
weights.setResearchAreaPoints(10); // "Area"
weights.setPreferredSupervisorPoints(15);
weights.setKeywordPoints(3); // "Word" + "Unit"??
weights.setResearchAreaPoints(5); // "Area"
weights.setPreferredSupervisorPoints(10);
}
private void setUpKeyWordTypes() {