From a29ca62bae9d0d689c66f2330fdf80dcc0f6c3b5 Mon Sep 17 00:00:00 2001 From: Emil Siverhall <emil-siv@dsv.su.se> Date: Mon, 27 Feb 2012 13:41:36 +0100 Subject: [PATCH 1/7] Added support for sortable params to KeywordDao --- .../match/dao/interfaces/KeywordDao.java | 40 +++++++++++++++++++ .../match/dao/jpa/KeywordDaoJPAImp.java | 21 ++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java b/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java index eb4d64b5a8..80e609f010 100644 --- a/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java +++ b/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java @@ -1,8 +1,10 @@ package se.su.dsv.scipro.match.dao.interfaces; +import java.io.Serializable; import java.util.List; import java.util.Set; +import se.su.dsv.scipro.data.dao.interfaces.Dao; import se.su.dsv.scipro.data.dao.interfaces.LazyDeleteDao; import se.su.dsv.scipro.match.dataobject.Keyword; import se.su.dsv.scipro.match.dataobject.KeywordType; @@ -10,6 +12,7 @@ import se.su.dsv.scipro.match.dataobject.KeywordType; public interface KeywordDao extends LazyDeleteDao<Keyword>{ Set<Keyword> getKeywords(KeywordType type, boolean includeDeleted); + List<Keyword> getKeywordList(Params params); public List<Keyword> findAllFromType(KeywordType kt, boolean includeDeleted); @@ -17,4 +20,41 @@ public interface KeywordDao extends LazyDeleteDao<Keyword>{ Keyword getKeywordByNameAndType(String keywordName, KeywordType type); + public static class Params extends Dao.SortableParams implements Serializable { + + private static final long serialVersionUID = 5317030582030781723L; + + private String keyword; + private KeywordType type; + private boolean includeDeleted = false; + + public Params() { + //Sort keywords on their name in ascending order as default when using Params + setSortOn("keyword", Sort.ASCENDING); + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public String getKeyword() { + return keyword; + } + + public void setType(KeywordType type) { + this.type = type; + } + + public KeywordType getType() { + return type; + } + + public void setIncludeDeleted(boolean includeDeleted) { + this.includeDeleted = includeDeleted; + } + + public boolean isIncludeDeleted() { + return includeDeleted; + } + } } diff --git a/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java b/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java index f1b466f4a7..9b4860b570 100644 --- a/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java +++ b/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java @@ -14,6 +14,7 @@ import org.springframework.orm.jpa.JpaCallback; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; +import se.su.dsv.scipro.data.dao.jpa.AbstractQuerySet; import se.su.dsv.scipro.data.dao.jpa.AbstractSortableQuerySet; import se.su.dsv.scipro.data.dao.jpa.LazyDeleteAbstractDaoJPAImp; import se.su.dsv.scipro.data.dao.jpa.Query; @@ -41,6 +42,18 @@ public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> imple } } + @Override + public List<Keyword> getKeywordList(Params params) { + return getJpaTemplate().execute(createQuerySet(params).fetchCallback()); + } + + private AbstractQuerySet<Keyword> createQuerySet(Params params) { + return new QuerySet() + .type(params.getType()) + .includeDeleted(params.isIncludeDeleted()) + .sort(params); + } + private static class QuerySet extends AbstractSortableQuerySet<Keyword> { public QuerySet() { super(Keyword.class); @@ -55,6 +68,14 @@ public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> imple return this; } + public QuerySet includeDeleted(boolean includeDeleted) { + if(!includeDeleted) { + getQuery().combine( + new Query().where("k.deleted = false")); + } + return this; + } + public QuerySet noDeleted() { getQuery().combine( new Query().where("k.deleted = false")); From e21b6c7039d368ab48a5d999b2186707761791dc Mon Sep 17 00:00:00 2001 From: Emil Siverhall <emil-siv@dsv.su.se> Date: Mon, 27 Feb 2012 13:42:11 +0100 Subject: [PATCH 2/7] changes in keyword data provider to match new params --- .../dataprovider/KeywordsDataProvider.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java b/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java index 82e4409e98..19c9e821fd 100644 --- a/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java +++ b/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java @@ -5,6 +5,7 @@ import java.util.Iterator; import org.apache.wicket.spring.injection.annot.SpringBean; import se.su.dsv.scipro.data.dao.interfaces.Dao; +import se.su.dsv.scipro.data.dao.interfaces.Dao.SortableParams.Sort; import se.su.dsv.scipro.dataproviders.SortSpecifier; import se.su.dsv.scipro.dataproviders.SortableDataProvider; import se.su.dsv.scipro.match.dao.interfaces.KeywordDao; @@ -15,29 +16,34 @@ public class KeywordsDataProvider extends SortableDataProvider<Keyword>{ private static final long serialVersionUID = 1L; - private KeywordType keywordType = null; - @SpringBean protected KeywordDao keywordDao; + private KeywordDao.Params params; @Override protected Dao<Keyword> getDao() { return keywordDao; } - public KeywordsDataProvider(final SortSpecifier sortSpecifier, KeywordType keywordType) { + public KeywordsDataProvider(KeywordType keywordType, boolean includeDeleted) { + this(null, keywordType, includeDeleted); + } + + public KeywordsDataProvider(final SortSpecifier sortSpecifier, KeywordType keywordType, boolean includeDeleted) { super(sortSpecifier, Keyword.class); - this.keywordType = keywordType; + params = new KeywordDao.Params(); + params.setIncludeDeleted(includeDeleted); + params.setType(keywordType); } public Iterator<Keyword> iterator(int first, int count) { - Iterator<Keyword> iter = keywordDao.getKeywords(keywordType, true).iterator(); + Iterator<Keyword> iter = keywordDao.getKeywordList(params).iterator(); return iter; } @Override public int size() { - return keywordDao.getKeywords(keywordType, true).size(); + return keywordDao.getKeywordList(params).size(); } } \ No newline at end of file From 9d7f9e4343132098bf8cda49810eb9425de57310 Mon Sep 17 00:00:00 2001 From: Emil Siverhall <emil-siv@dsv.su.se> Date: Mon, 27 Feb 2012 13:43:50 +0100 Subject: [PATCH 3/7] Switched to new param implementation when retrieving keywords on a few pages --- .../admin/panels/match/ManageKeywordPanel.java | 2 +- .../match/panel/FilterFormKeywordPanel.java | 6 ++++-- .../project/panels/KeywordSelectionPanel.java | 16 +++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java b/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java index a75eca0610..631bae94a0 100644 --- a/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java +++ b/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java @@ -58,7 +58,7 @@ public class ManageKeywordPanel extends Panel { dialog.add(new EmptyPanel("dialogContent")); dialog.setOutputMarkupId(true); - keywordsDataProvider = new KeywordsDataProvider(null, keywordType); + keywordsDataProvider = new KeywordsDataProvider(keywordType, true); tableContainer = new WebMarkupContainer("table"); tableContainer.setOutputMarkupId(true); diff --git a/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java b/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java index 707767139c..76510c3fd1 100644 --- a/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java +++ b/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java @@ -47,8 +47,10 @@ public class FilterFormKeywordPanel extends Panel { KeywordType kwType = keywordTypeDao.findByType(type); - Set<Keyword> tmpWords = keywordDao.getKeywords(kwType, true); - keywords = new ArrayList<Keyword>(tmpWords); + KeywordDao.Params params = new KeywordDao.Params(); + params.setType(kwType); + params.setIncludeDeleted(true); + keywords = keywordDao.getKeywordList(params); CompoundPropertyModel<List<Keyword>> keyWordModel = new CompoundPropertyModel<List<Keyword>>(keywords); checkGroup = new CheckGroup<Keyword>("checkGroup", new ArrayList<Keyword>()); diff --git a/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java b/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java index b76ca424a8..ae907f9960 100644 --- a/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java +++ b/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java @@ -133,8 +133,9 @@ public class KeywordSelectionPanel extends Panel { if (keywordProvider.getObject() != null) { ideaAreaKeywords = new ArrayList<Keyword>(keywordProvider.getObject().getKeywords().getFiltered(area)); } - Set<Keyword> areaKeySet = keywordDao.getKeywords(area, false); - List<Keyword> areaKeyList = new ArrayList<Keyword>(areaKeySet); + KeywordDao.Params params = new KeywordDao.Params(); + params.setType(area); + List<Keyword> areaKeyList = keywordDao.getKeywordList(params); CompoundPropertyModel<List<Keyword>> listModel = new CompoundPropertyModel<List<Keyword>>(areaKeyList); researchAreaGroup = new CheckGroup<Keyword>("researchAreaGroup", ideaAreaKeywords); @@ -162,13 +163,18 @@ public class KeywordSelectionPanel extends Panel { } } private void addRegularKeywordSelection() { - KeywordType keyword = keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR); - List<Keyword> selectedWords = keywordProvider.getObject().getKeywords().getFiltered(keyword); + KeywordType keywordType = keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR); + List<Keyword> selectedWords = keywordProvider.getObject().getKeywords().getFiltered(keywordType); ideaKeywords = new ArrayList<Keyword>(); if(!selectedWords.isEmpty()) ideaKeywords = new ArrayList<Keyword>(selectedWords); - Set<Keyword> keySet = keywordDao.getKeywords(keyword, false); + KeywordDao.Params params = new KeywordDao.Params(); + params.setType(keywordType); + + List<Keyword> keywordList = keywordDao.getKeywordList(params); + Set<Keyword> keySet = new HashSet<Keyword>(keywordList); + //Set<Keyword> keySet = keywordDao.getKeywords(keywordType, false); regularKeywordsPalette = new Palette<Keyword>("keywordPalette", new ListModel<Keyword>(ideaKeywords), new CollectionModel<Keyword>(keySet), From 974f95864cbe412e4149a2c12ed5b78064351414 Mon Sep 17 00:00:00 2001 From: Emil Siverhall <emil-siv@dsv.su.se> Date: Mon, 27 Feb 2012 13:44:20 +0100 Subject: [PATCH 4/7] unit test for new keyword dao method --- .../java/se/su/dsv/scipro/match/dao/TestKeywordDao.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java b/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java index e7dfbf2b91..ecdde37710 100644 --- a/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java +++ b/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java @@ -1,6 +1,7 @@ package se.su.dsv.scipro.match.dao; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.junit.Assert; @@ -70,6 +71,12 @@ public class TestKeywordDao { Set<Keyword> keywords = target.getKeywords(standard, true); Assert.assertEquals(new HashSet<Keyword>( Arrays.asList(new Keyword[] { keyword1, keyword2 })), keywords); + + KeywordDao.Params params = new KeywordDao.Params(); + params.setType(standard); + + List<Keyword> keywordList = target.getKeywordList(params); + Assert.assertEquals(Arrays.asList(new Keyword[]{keyword1, keyword2}), keywordList); } @Test From f547468a501eae756f15d7cde2227502891e4d4e Mon Sep 17 00:00:00 2001 From: Tom Vahlman <tom@dsv.su.se> Date: Mon, 27 Feb 2012 16:32:01 +0100 Subject: [PATCH 5/7] Added a test with three project ideas which where matched against three supervisors. There is a need for more extensive tests for covering all cases. --- .../match/TestGreedyMatchingAlgorithm.java | 249 ++++++++++++++---- 1 file changed, 197 insertions(+), 52 deletions(-) diff --git a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java index 541f700bc2..998d5fd839 100644 --- a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java +++ b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java @@ -71,8 +71,9 @@ public class TestGreedyMatchingAlgorithm { private Set<Language> languages; private KeywordType keywordTypeArea; private KeywordType keywordTypeWord; + private ApplicationPeriod applicationPeriod; - private Employee createSupervisor(final String firstName, final String lastName, Set<Language> languages1) { + private Employee createEmployee(final String firstName, final String lastName, Set<Language> languages1) { Employee employee = new Employee(); User user = new User(); user.setFirstName(firstName); @@ -109,17 +110,30 @@ public class TestGreedyMatchingAlgorithm { keywordTypeWord = keywordTypeDao.save(new KeywordType("Word")); } - private void addKeyWords(final Employee supervisor, final ProjectIdea projectIdea, final Keyword keyword) { - supervisor.getKeywords().getAll().add(keyword); - projectIdea.getKeywords().getAll().add(keyword); + private void addKeyWords(List<Employee> supervisorList, List<ProjectIdea> projectIdeaList, final Keyword keyword) { + if(supervisorList != null && !supervisorList.isEmpty()) { + for(int i = 0; i < supervisorList.size(); i++) { + supervisorList.get(i).getKeywords().getAll().add(keyword); + } + } + if(projectIdeaList != null && !projectIdeaList.isEmpty()) { + for(int i = 0; i < projectIdeaList.size(); i++) { + projectIdeaList.get(i).getKeywords().getAll().add(keyword); + } + } } private Keyword createKeyword(final KeywordType keyWordType , final String keyWordName, final boolean deleted) { - Keyword keyword = new Keyword(); - keyword.setType(keyWordType); - keyword.setKeyword(keyWordName); - keyword.setDeleted(deleted); - return keywordDao.save(keyword); + Keyword keyword = keywordDao.getKeywordByNameAndType(keyWordName, keyWordType); + if(keyword == null) { + keyword = new Keyword(); + keyword.setType(keyWordType); + keyword.setKeyword(keyWordName); + keyword.setDeleted(deleted); + return keywordDao.save(keyword); + } else { + return keyword; + } } @Before @@ -131,17 +145,17 @@ public class TestGreedyMatchingAlgorithm { languages = new HashSet<Language>(); languages.add(languageDao.save(new Language("Swedish"))); languages.add(languageDao.save(new Language("English"))); - bachelorSupervisor = createSupervisor("Henrik", "Hansson", languages); + bachelorSupervisor = createEmployee("Henrik", "Hansson", languages); bachelorProjectClass = createProjectClass(ProjectClass.BACHELOR, "Bachelor", "Bachelor project class"); Set<ProjectClass> projectClassSet = new HashSet<ProjectClass>(); projectClassSet.add(bachelorProjectClass); projectClassSet.add(masterProjectClass); List<ApplicationPeriod> myList = new ArrayList<ApplicationPeriod>(); myList.addAll(applicationPeriodDao.findAll()); - ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriod(projectClassSet, "name1"); + applicationPeriod = applicationPeriodFacade.createApplicationPeriod(projectClassSet, "name1"); bachelorProjectIdea = createProjectIdea(bachelorProjectClass, applicationPeriod); - masterSupervisor = createSupervisor("Birger", "Andersson", languages); + masterSupervisor = createEmployee("Birger", "Andersson", languages); masterProjectClass = createProjectClass(ProjectClass.MASTER, "Master", "Master project class"); masterProjectIdea = createProjectIdea(masterProjectClass, applicationPeriod); } @@ -239,10 +253,14 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a bachelor supervisor can handle a projectIdea which has been rejected by another (bachelor) supervisor, even if the other supervisor has a higher score */ public void testRejectByOtherSupervisor() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false)); // 3 + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false)); // 3 addRejectedMatch(bachelorSupervisor2, bachelorProjectIdea); unmatchedProjectIdeas.add(bachelorProjectIdea); Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); @@ -256,7 +274,7 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a preferred bachelor supervisor should be chosen prior to another bachelor supervisor */ public void testPreferredSupervisor() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor2); @@ -274,7 +292,7 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a preferred "bachelor" supervisor should NOT handle a master projectIdea */ public void testIncorrectProjectClass() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(masterSupervisor, 0L, 1, masterProjectClass)); masterProjectIdea.setPreferredSupervisor(bachelorSupervisor2); @@ -291,10 +309,14 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* keywords of 16 points should supersede a preferred supervisor of 15 points */ public void testHighestScore() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeArea, "test area", false)); // 10 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false)); // 3 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Java", false)); // 3 + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeArea, "test area", false)); // 10 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false)); // 3 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Java", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor); // 15 @@ -311,10 +333,16 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* keywords of 6 points should supersede keywords of 3 points */ public void testHighestScore_v2() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false)); // 3 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false)); // 3 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false)); // 3 + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false)); // 3 + supervisorList.clear(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); // 3 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -330,10 +358,16 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* deleted keywords of 6 points should NOT supersede valid keywords of 3 points */ public void testHighestScore_v3() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false)); // 3 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", true)); // 3 - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", true)); // 3 + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false)); // 3 + supervisorList.clear(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", true)); // 3 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", true)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -352,18 +386,23 @@ public class TestGreedyMatchingAlgorithm { Set<Language> languageSet = new HashSet<Language>(); Language language_sv = languageDao.save(new Language("Swedish")); languageSet.add(language_sv); - Employee bachelorSupervisor_sv = createSupervisor("David", "Hallberg", languageSet); + Employee bachelorSupervisor_sv = createEmployee("David", "Hallberg", languageSet); bachelorSupervisor.getCapabilities().getLanguages().clear(); bachelorSupervisor.getCapabilities().getLanguages().add(languageDao.save(new Language("English"))); bachelorProjectIdea.getLanguages().clear(); bachelorProjectIdea.getLanguages().add(language_sv); bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor); // 15 - - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "C++", false)); // 3 - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Java", false)); // 3 - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false)); // 3 - addKeyWords(bachelorSupervisor_sv, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false)); // 3 + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "C++", false)); // 3 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Java", false)); // 3 + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false)); // 3 + supervisorList.clear(); + supervisorList.add(bachelorSupervisor_sv); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor_sv, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -379,10 +418,14 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a supervisor should not be chosen if he/she is "deleted" */ public void testForDeletedSupervisor() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); bachelorSupervisor2.setDeleted(true); - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false)); // 3 + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -399,13 +442,16 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a supervisor cannot be supervisor to herself */ public void testSupervisorCannotSuperviseHerself() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); Role role = new Student(); role.setUser(bachelorSupervisor2.getUser()); role = roleDao.save(role); bachelorProjectIdea.getAuthors().add((Student) role); - - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false)); // 3 + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -422,8 +468,12 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* the supervisor with no available "slots" should NOT be chosen even when this supervisor has the highest score */ public void testNoAvailableSlots() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false)); // 3 + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 1L, 1, bachelorProjectClass)); // availability = numCapable - numMatched unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -441,9 +491,12 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* a supervisor with the highest available slot should NOT be chosen when this supervisor has less score */ public void testHighestAvailableSlot() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); - - addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false)); // 3 + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); // 3 supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 4, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -460,7 +513,7 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* test that the number Availability#numMatched has increased with one and that the supervisor with highest available slots are chosen */ public void testNumMatchedHasIncreased() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 4, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); @@ -497,10 +550,14 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* neither a bachelor or a master supervisor are preferred to handle a bachelor idea when compatibility, keywords, scores etc are equal */ public void testBachelorOrMaster() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(masterSupervisor, 0L, 1, bachelorProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); - addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false)); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(bachelorSupervisor2); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false)); unmatchedProjectIdeas.add(bachelorProjectIdea); Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); assertTrue(result.matches.size() > 0); @@ -514,7 +571,7 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */ public void testSlotForMasterSupervisor() { -//Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); +//Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass)); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, bachelorProjectClass)); //supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); @@ -531,7 +588,7 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */ public void testIncreaseSlotForMasterSupervisor() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass)); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); @@ -561,7 +618,10 @@ public class TestGreedyMatchingAlgorithm { @Rollback /* test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */ public void testIncreaseSlotForMasterSupervisor_v2() { - Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages); + /* + supervisorAvailability.clear(); + unmatchedProjectIdeas.clear(); + Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass)); supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass)); supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); @@ -569,7 +629,11 @@ public class TestGreedyMatchingAlgorithm { unmatchedProjectIdeas.add(masterProjectIdea); bachelorProjectIdea.setPreferredSupervisor(masterSupervisor); masterProjectIdea.setPreferredSupervisor(masterSupervisor); - addKeyWords(masterSupervisor, masterProjectIdea, createKeyword(keywordTypeWord, "UML", false)); + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + projectIdeaList.add(bachelorProjectIdea); + List<Employee> supervisorList = new ArrayList<Employee>(); + supervisorList.add(masterSupervisor); + addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); assertTrue(result.matches.size() > 0); boolean foundMasterProjIdea = false; @@ -593,7 +657,88 @@ public class TestGreedyMatchingAlgorithm { assertTrue(foundBachelorProjIdea); assertTrue(foundBachelorSuperVisor); assertTrue(foundMasterSuperVisor); - assertTrue(result.unmatched.size() == 0); + assertTrue(result.unmatched.size() == 0); */ } + @Test + @Transactional + @Rollback + /* three supervisors which are matched against three project ideas */ + public void testIncreaseSlotForMasterSupervisor_v3() { + List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); + List<Employee> supervisorList = new ArrayList<Employee>(); + + Employee davidH = createEmployee("David", "Hallberg", languages); + supervisorAvailability.clear(); + supervisorAvailability.add(new Availability(davidH, 0L, 5, bachelorProjectClass)); + supervisorAvailability.add(new Availability(davidH, 0L, 5, masterProjectClass)); + + supervisorList.clear(); + supervisorList.add(davidH); + addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "IT för lärande", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Business process management (BPM)", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Flexibelt lärande", false)); + + Employee henrikH = createEmployee("Henrik", "Hansson", languages); + supervisorAvailability.add(new Availability(henrikH, 0L, 5, bachelorProjectClass)); + supervisorAvailability.add(new Availability(henrikH, 0L, 5, masterProjectClass)); + + supervisorList.clear(); + supervisorList.add(henrikH); + addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "Technology Enhanced Learning", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "ICT for Development", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Flexibelt lärande", false)); + + Employee henrikBergstr = createEmployee("Henrik", "Bergström", languages); // login henrikbe + supervisorAvailability.add(new Availability(henrikBergstr, 0L, 5, bachelorProjectClass)); + supervisorAvailability.add(new Availability(henrikBergstr, 0L, 5, masterProjectClass)); + + supervisorList.clear(); + supervisorList.add(henrikBergstr); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "ACT Agera i kommunikation med teknik", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "System development", false)); + addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "IT-architectures", false)); + + ProjectIdea firstBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod); + projectIdeaList.clear(); + projectIdeaList.add(firstBachelorIdea); // no preferred supervisor for this project idea + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "ICT for Development", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "System development", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "Enterprise 2.0", false)); + + ProjectIdea masterIdea = createProjectIdea(masterProjectClass, applicationPeriod); + projectIdeaList.clear(); + projectIdeaList.add(masterIdea); // no preferred supervisor for this project idea + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "Interaction design", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "ICT for Development", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "Digital Systems Security", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "System development", false)); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "Information system theory", false)); + + ProjectIdea secondBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod); + projectIdeaList.clear(); + projectIdeaList.add(secondBachelorIdea); // David Hallberg is preferred supervisor for this project idea + secondBachelorIdea.setPreferredSupervisor(davidH); + addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "E-government and E-democracy", false)); + + unmatchedProjectIdeas.clear(); + unmatchedProjectIdeas.add(firstBachelorIdea); + unmatchedProjectIdeas.add(secondBachelorIdea); + unmatchedProjectIdeas.add(masterIdea); + + Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); + assertTrue(result.matches.size() == 3); + + assertTrue(result.matches.get(0).getPoints() == 10); + assertTrue(result.matches.get(1).getPoints() == 5); + assertTrue(result.matches.get(2).getPoints() == 5); + + assertTrue(result.matches.get(0).getSupervisor().equals(davidH)); + assertTrue(result.matches.get(1).getSupervisor().equals(henrikH)); + assertTrue(result.matches.get(2).getSupervisor().equals(henrikH)); + + assertTrue(result.matches.get(0).getProjectIdea().equals(secondBachelorIdea)); + assertTrue(result.matches.get(1).getProjectIdea().equals(firstBachelorIdea)); + assertTrue(result.matches.get(2).getProjectIdea().equals(masterIdea)); + } } From 604a38152c3e5739d4d3f73eb4ab9808ebf0d312 Mon Sep 17 00:00:00 2001 From: Tom Vahlman <tom@dsv.su.se> Date: Mon, 27 Feb 2012 21:33:06 +0100 Subject: [PATCH 6/7] We must sort on the highest (individual availability) when the project classes are the same. --- .../scipro/match/GreedyMatchingAlgorithm.java | 4 +- .../scipro/match/dataobject/Availability.java | 13 ++- .../match/TestGreedyMatchingAlgorithm.java | 89 +++++++------------ 3 files changed, 45 insertions(+), 61 deletions(-) diff --git a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java index 9ffe337766..1a7a45b8f2 100644 --- a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java +++ b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java @@ -280,8 +280,8 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm { } 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; + } else { // the project class is the same sort on the highest availability + return availability.compareTo(otherPair.getAvailability()); } } } diff --git a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java index ac83863365..3f06503a3f 100644 --- a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java +++ b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java @@ -8,7 +8,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectClass; /** * A class that specifies how available a supervisor is(in terms of thesis supervision) */ -public class Availability implements Serializable { +public class Availability implements Serializable, Comparable<Availability> { private static final long serialVersionUID = 1L; @@ -54,6 +54,17 @@ public class Availability implements Serializable { numMatched = num; } + @Override + public int compareTo(Availability availability) { + if(getAvailability() > availability.getAvailability()) { + return -1; + } else if(availability.getAvailability() > getAvailability()) { + return 1; + } else { + return 0; + } + } + @Override public String toString() { return "Availability [supervisorId=" + supervisor + ", numMatched=" diff --git a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java index 998d5fd839..9e66082e26 100644 --- a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java +++ b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java @@ -578,6 +578,7 @@ public class TestGreedyMatchingAlgorithm { unmatchedProjectIdeas.add(bachelorProjectIdea); Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); assertTrue(result.matches.size() > 0); + assertTrue(result.matches.get(0).getProjectIdea().equals(bachelorProjectIdea)); assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor)); assertTrue(result.unmatched.size() == 0); @@ -586,78 +587,50 @@ public class TestGreedyMatchingAlgorithm { @Test @Transactional @Rollback - /* test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */ + /* test that the supervisor who has the highest total slot available will be chosen */ public void testIncreaseSlotForMasterSupervisor() { - Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); - supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass)); - supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass)); - supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); - unmatchedProjectIdeas.add(bachelorProjectIdea); - bachelorProjectIdea.setPreferredSupervisor(masterSupervisor); - Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); - assertTrue(result.matches.size() > 0); - assertTrue(result.matches.get(0).getProjectIdea().equals(bachelorProjectIdea)); - assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor)); - assertTrue(result.unmatched.size() == 0); -// increase num capable for the supervisor + Employee davidH = createEmployee("David", "Hallberg", languages); + Employee henrikH = createEmployee("Henrik", "Hansson", languages); +//ProjectIdea firstBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod); + supervisorAvailability.add(new Availability(henrikH, 2L, 3, bachelorProjectClass)); // total slot = 2 + supervisorAvailability.add(new Availability(henrikH, 3L, 4, masterProjectClass)); + supervisorAvailability.add(new Availability(davidH, 1L, 1, bachelorProjectClass)); // total slot = 1 + supervisorAvailability.add(new Availability(davidH, 0L, 1, masterProjectClass)); unmatchedProjectIdeas.add(masterProjectIdea); - for (Availability availability : supervisorAvailability) { - if(availability.getProjectClass().equals(masterProjectClass)) { - availability.setNumCapable(availability.getNumCapable() + 1); - } - } - result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); + unmatchedProjectIdeas.add(bachelorProjectIdea); + + Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); assertTrue(result.matches.size() > 0); assertTrue(result.matches.get(0).getProjectIdea().equals(masterProjectIdea)); - assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor)); + assertTrue(result.matches.get(0).getSupervisor().equals(henrikH)); + assertTrue(result.matches.get(1).getProjectIdea().equals(bachelorProjectIdea)); + assertTrue(result.matches.get(1).getSupervisor().equals(henrikH)); assertTrue(result.unmatched.size() == 0); } @Test @Transactional @Rollback - /* test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */ + /* test that a master supervisor is chosen for a master project idea which has the same points as a bachelor project idea */ public void testIncreaseSlotForMasterSupervisor_v2() { - /* - supervisorAvailability.clear(); - unmatchedProjectIdeas.clear(); - Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages); - supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass)); - supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass)); - supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass)); + Employee davidH = createEmployee("David", "Hallberg", languages); + Employee henrikH = createEmployee("Henrik", "Hansson", languages); + supervisorAvailability.add(new Availability(henrikH, 3L, 3, bachelorProjectClass)); + supervisorAvailability.add(new Availability(henrikH, 3L, 4, masterProjectClass)); + supervisorAvailability.add(new Availability(davidH, 0L, 1, bachelorProjectClass)); unmatchedProjectIdeas.add(bachelorProjectIdea); unmatchedProjectIdeas.add(masterProjectIdea); - bachelorProjectIdea.setPreferredSupervisor(masterSupervisor); - masterProjectIdea.setPreferredSupervisor(masterSupervisor); - List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>(); - projectIdeaList.add(bachelorProjectIdea); - List<Employee> supervisorList = new ArrayList<Employee>(); - supervisorList.add(masterSupervisor); - addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false)); + bachelorProjectIdea.setPreferredSupervisor(henrikH); + masterProjectIdea.setPreferredSupervisor(henrikH); Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights); - assertTrue(result.matches.size() > 0); - boolean foundMasterProjIdea = false; - boolean foundMasterSuperVisor= false; - - boolean foundBachelorProjIdea = false; - boolean foundBachelorSuperVisor= false; - - for(Match match : result.matches) { - if(match.getProjectIdea().equals(masterProjectIdea) && match.getSupervisor().equals(masterSupervisor)) { - foundMasterProjIdea = true; - foundMasterSuperVisor = true; - } - - if(match.getProjectIdea().equals(bachelorProjectIdea) && match.getSupervisor().equals(bachelorSupervisor2)) { - foundBachelorProjIdea = true; - foundBachelorSuperVisor = true; - } - } - assertTrue(foundMasterProjIdea); - assertTrue(foundBachelorProjIdea); - assertTrue(foundBachelorSuperVisor); - assertTrue(foundMasterSuperVisor); - assertTrue(result.unmatched.size() == 0); */ + assertTrue(result.matches.size() > 0); + assertTrue(result.matches.get(0).getPoints() == 10); + assertTrue(result.matches.get(1).getPoints() == 0); + assertTrue(result.matches.get(0).getSupervisor().equals(henrikH)); + assertTrue(result.matches.get(1).getSupervisor().equals(davidH)); + assertTrue(result.matches.get(0).getProjectIdea().equals(masterProjectIdea)); + assertTrue(result.matches.get(1).getProjectIdea().equals(bachelorProjectIdea)); + assertTrue(result.unmatched.size() == 0); } @Test From 91f9a4584b553623a2f124bed32bf60e08219c9f Mon Sep 17 00:00:00 2001 From: Tom Vahlman <tom@dsv.su.se> Date: Mon, 27 Feb 2012 21:57:27 +0100 Subject: [PATCH 7/7] Moved the availability comparison to the class Pair. Tests should be written for this... --- .../scipro/match/GreedyMatchingAlgorithm.java | 35 +++++++++++-------- .../scipro/match/dataobject/Availability.java | 15 ++------ 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java index 1a7a45b8f2..8aa6930b03 100644 --- a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java +++ b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java @@ -263,7 +263,7 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm { */ @Override public int compareTo(Pair otherPair) { - if(match.getPoints() > otherPair.getMatch().getPoints()) { + if(match.getPoints() > otherPair.getMatch().getPoints()) { // points is the most important criteria return -1; } else if(otherPair.getMatch().getPoints() > match.getPoints()) { return 1; @@ -272,20 +272,27 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm { 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 project class is the same sort on the highest availability - return availability.compareTo(otherPair.getAvailability()); + } else { + // we must now sort on Project Class because a master supervisor can supervise both a master project idea and + // a bachelor project idea, however the "best" match is if a "master supervisor" handles 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 most suited supervisor is now the one that has highest slots for the specific project class + if(availability.getAvailability() > otherPair.getAvailability().getAvailability()) { + return -1; + } else if(otherPair.getAvailability().getAvailability() > availability.getAvailability()) { + return 1; + } else { // the project classes is the same + return 0; + } + } } } } - } - - } + } } \ No newline at end of file diff --git a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java index 3f06503a3f..954e152d9d 100644 --- a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java +++ b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java @@ -8,7 +8,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectClass; /** * A class that specifies how available a supervisor is(in terms of thesis supervision) */ -public class Availability implements Serializable, Comparable<Availability> { +public class Availability implements Serializable { private static final long serialVersionUID = 1L; @@ -53,18 +53,7 @@ public class Availability implements Serializable, Comparable<Availability> { public void setNumMatched(Long num) { numMatched = num; } - - @Override - public int compareTo(Availability availability) { - if(getAvailability() > availability.getAvailability()) { - return -1; - } else if(availability.getAvailability() > getAvailability()) { - return 1; - } else { - return 0; - } - } - + @Override public String toString() { return "Availability [supervisorId=" + supervisor + ", numMatched="