def test_case18(self):
        """Testing the isValid function - passing a null graph"""

        graph = BipartiteGraph()
        solution = Solution(graph)
        
        result = solution.isValid(self.students,self.supervisors)

        self.assertFalse(result)
    def test_case22(self):
        """Testing the isValid function - when a supervisor's degree is 0"""

        self.graph1.removeEdge("supervisor3","student1")

        solution = Solution(self.graph1)

        result = solution.isValid(self.students,self.supervisors)

        self.assertFalse(result)
    def test_case23(self):
        """Testing the isValid function - when a student's degree is not equal to 1"""

        self.graph1.addEdge("supervisor2","student3")

        solution = Solution(self.graph1)

        result = solution.isValid(self.students,self.supervisors)

        self.assertFalse(result)
    def test_case21(self):
        """Testing the isValid function - when a supervisor's allocation exceeds their quota"""

        self.graph1.addEdge("supervisor3","student2")

        solution = Solution(self.graph1)

        result = solution.isValid(self.students,self.supervisors)

        self.assertFalse(result)
    def test_case6(self):
        """Testing similarity function with 2 identical profiles (1)"""

        dummySolution = Solution()

        supervisorKeywords = self.supervisors["supervisor3"].getKeywords()
        studentKeywords = self.students["student4"].getKeywords()
        
        f_stu,f_sup = dummySolution.kw_similarity(studentKeywords,supervisorKeywords,self.rankWeights)

        self.assertEqual((f_stu,f_sup),(1,1))
示例#6
0
    def test_case8(self):
        """Testing the create random graph function"""

        graph = BipartiteGraph.createRandomGraph(self.students,
                                                 self.supervisors)

        solution = Solution(graph)

        result = solution.isValid(self.students, self.supervisors)

        self.assertTrue(result)
    def test_case20(self):
        """Testing the isValid function - when number of students less than actual"""

        graph = BipartiteGraph()
        
        graph.addEdge("supervisor1","student1")
        graph.addEdge("supervisor3","student3")
        graph.addEdge("supervisor2","student2")

        solution = Solution(graph)

        result = solution.isValid(self.students,self.supervisors)

        self.assertFalse(result)
示例#8
0
    def setUp(self):

        self.students, self.supervisors = createRandomData(4, 8, 18)

        # Generating rank weights for c = 0.5
        self.rankWeights = Solution.calcRankWeights()

        #Creating fitness cache

        self.dummySolution = Solution()
        self.fitnessCache = {}
        for sup in self.supervisors:
            supervisorKeywords = self.supervisors[sup].getKeywords()
            for stu in self.students:
                studentKeywords = self.students[stu].getKeywords()
                f_stu, f_sup = self.dummySolution.kw_similarity(
                    studentKeywords, supervisorKeywords, self.rankWeights)
                self.fitnessCache[str((stu, sup))] = (f_stu, f_sup)

        #Setting up the GA Object

        self.mutationOp = mutate
        self.selectionOp = tournamentSelection
        self.crossoverOp = crossover

        self.geneticAlgorithm = GeneticAlgorithm(
            self.students, self.supervisors, self.fitnessCache,
            self.rankWeights, self.mutationOp, self.crossoverOp,
            self.selectionOp)

        #Parameters for GA

        self.numberOfGenerations = 20
        self.populationSize = 10
        self.mutationProbability = 0.1
        self.swapProbability = 0.3
        self.transferProbability = 0.5

        #Initializing population
        self.population = self.geneticAlgorithm.initializePopulation(
            self.populationSize)
        self.maxFst = max(self.population, key=lambda x: x.getFst()).getFst()
        self.minFst = min(self.population, key=lambda x: x.getFst()).getFst()

        self.maxFsup = max(self.population,
                           key=lambda x: x.getFsup()).getFsup()
        self.minFsup = min(self.population,
                           key=lambda x: x.getFsup()).getFsup()
    def test_case4(self):
        """Testing the calculate rank weights function when c=0 and n=0"""

        rankWeights = Solution.calcRankWeights(c=0,n=0)
        expected = {}

        self.assertEqual(rankWeights,expected)
示例#10
0
    def test_case6(self):
        """Testing the K Point Crossover function - for random 3sup:4stu solution"""

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)
        solution2 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution3 = kPoint(solution1,
                           solution2,
                           self.supervisors,
                           self.students,
                           k=3)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)
    def test_case5(self):
        """Testing similarity function with 2 non-similar profiles (0)"""

        dummySolution = Solution()

        supervisorKeywords = self.supervisors["supervisor3"].getKeywords()
        studentKeywords = self.students["student1"].getKeywords()
        
        f_stu,f_sup = dummySolution.kw_similarity(studentKeywords,supervisorKeywords,self.rankWeights)

        expected_fstu = 0.1217742
        expected_fsup = 0.1416129

        expected = (round(expected_fstu,6),round(expected_fsup,6))
        retrieved = (round(f_stu,6),round(f_sup,6))
        
        self.assertEqual(retrieved,expected)
    def test_case1(self):
        """Testing the create random solution function"""

        solution1 = Solution.generateRandomSolution(self.students,self.supervisors)
        
        result = solution1.isValid(self.students,self.supervisors)

        self.assertEqual(result,True)
    def test_case8(self):
        """Testing similarity function between 2 less similar profiles """
        
        dummySolution = Solution()

        supervisorKeywords = self.supervisors["supervisor3"].getKeywords()
        studentKeywords = self.students["student2"].getKeywords()

        f_stu,f_sup = dummySolution.kw_similarity(studentKeywords,supervisorKeywords,self.rankWeights)

        expected_fstu = 0.255645
        expected_fsup = 0.522043

        expected = (round(expected_fstu,6),round(expected_fsup,6))
        retrieved = (round(f_stu,6),round(f_sup,6))

        self.assertEqual(retrieved,expected)
示例#14
0
    def test_case13(self):
        """Testing the kPoint crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = kPoint(solution1,
                           solution2,
                           self.supervisors2,
                           self.students2,
                           k=15)

        result = solution3.isValid(self.students2, self.supervisors2)

        self.assertTrue(result)
示例#15
0
    def test_case11(self):
        """Testing the ERX Modified crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = crossover(solution1, solution2, self.supervisors,
                              self.supervisors2, self.students2)

        structureResult = (solution3.getGraph().getStructure()
                           == solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students2,
                                    self.supervisors2)) and (structureResult)

        self.assertTrue(result)
    def test_case6(self):
        """Testing mutation function for a randomly created solution 2"""

        mutationProbability = 0.3
        swapProbability = 0.7
        transferProbability = 0

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution2 = mutate(solution1, self.supervisors, mutationProbability,
                           swapProbability, transferProbability)

        result = solution2.isValid(self.students, self.supervisors)

        self.assertTrue(result)
    def test_case2(self):
        """Testing the calculate Rank Weights function when c = 1"""

        rankWeights = Solution.calcRankWeights(c=1)

        result = True
        
        expected = 0.2
        
        for i in rankWeights:

            if rankWeights[i] != expected:

                result = False
                break

        self.assertTrue(result)
    def test_case3(self):
        """Testing the calculate rank weights function when c = 0.3"""

        rankWeights = Solution.calcRankWeights(c=0.3)

        result = round(sum(rankWeights.values()),15)

        expected = {1: 0.701705143, 2: 0.210511543, 3: 0.063153463, 4: 0.0189460389, 5: 0.005683812}

        result2 = True

        for i in rankWeights:

            if round(rankWeights[i],8) != round(expected[i],8):
                result2 = False
                break
        

        self.assertEqual((result,result2),(1,True))
def uniform(solution1, solution2, supervisors, students, k=None):
    """
    An implementation of uniform crossover
    """
    graph1 = solution1.getGraph()
    graph2 = solution2.getGraph()

    stuEdges1 = graph1.getStuEdges()
    stuEdges2 = graph2.getStuEdges()

    g = BipartiteGraph()
    for stu in students:
        if random.random() < 0.5:
            sup = stuEdges1[stu][0]
        else:
            sup = stuEdges2[stu][0]
        g.addEdge(sup, stu)

    fixSolution(g, supervisors, students)
    return Solution(g)
def sp_crossover(solution1,
                 solution2,
                 supervisors=None,
                 students=None,
                 k=None):
    #print("New case!!")
    graph1 = solution1.getGraph()
    graph2 = solution2.getGraph()
    already_set = set()

    mergedGraph = graph1.merge(graph2)

    stf1 = solution1.getStructuralFitness(supervisors)
    stf2 = solution2.getStructuralFitness(supervisors)

    if random.random() <= (stf1) / (stf1 + stf2):
        structure = graph1.getStructure()
    else:
        structure = graph2.getStructure()

    original_structure = dict(structure)

    result = hopkroft(mergedGraph, original_structure)
    return Solution(result)
示例#21
0
    def initializePopulation(self,size):
        """
        Function to create a pool of random solutions of a given size.
        Used in the begining of the GA run to create intial population.

        Parameters:
            size (int) - the size of the population.

        Returns:

            population (list) - list containing 'n' randomly created Solution Objects, where n is the specified size.
        """

        population = []
        
        count = 0
        while count < size:
            #Generate random solution, calculate and set Fst and Fsup values, then append to population list until its of the size we want.

            new = Solution.generateRandomSolution(self.students,self.supervisors)
            new.calcFitness(self.students,self.supervisors,self.rankWeights,self.fitnessCache)
            population.append(new)
            count+=1
        return population
    def test_case27(self):
        """Testing 'dominates' function - when Fsup is same in solution2 and solution1"""

        solution1 = Solution()
        solution2 = Solution()

        solution1.setFst(29.5)
        solution1.setFsup(0.4)

        solution2.setFst(27.5)
        solution2.setFsup(0.4)

        result = solution1.dominates(solution2)

        self.assertTrue(result)
示例#23
0
class GATest(unittest.TestCase):
    def setUp(self):

        self.students, self.supervisors = createRandomData(4, 8, 18)

        # Generating rank weights for c = 0.5
        self.rankWeights = Solution.calcRankWeights()

        #Creating fitness cache

        self.dummySolution = Solution()
        self.fitnessCache = {}
        for sup in self.supervisors:
            supervisorKeywords = self.supervisors[sup].getKeywords()
            for stu in self.students:
                studentKeywords = self.students[stu].getKeywords()
                f_stu, f_sup = self.dummySolution.kw_similarity(
                    studentKeywords, supervisorKeywords, self.rankWeights)
                self.fitnessCache[str((stu, sup))] = (f_stu, f_sup)

        #Setting up the GA Object

        self.mutationOp = mutate
        self.selectionOp = tournamentSelection
        self.crossoverOp = crossover

        self.geneticAlgorithm = GeneticAlgorithm(
            self.students, self.supervisors, self.fitnessCache,
            self.rankWeights, self.mutationOp, self.crossoverOp,
            self.selectionOp)

        #Parameters for GA

        self.numberOfGenerations = 20
        self.populationSize = 10
        self.mutationProbability = 0.1
        self.swapProbability = 0.3
        self.transferProbability = 0.5

        #Initializing population
        self.population = self.geneticAlgorithm.initializePopulation(
            self.populationSize)
        self.maxFst = max(self.population, key=lambda x: x.getFst()).getFst()
        self.minFst = min(self.population, key=lambda x: x.getFst()).getFst()

        self.maxFsup = max(self.population,
                           key=lambda x: x.getFsup()).getFsup()
        self.minFsup = min(self.population,
                           key=lambda x: x.getFsup()).getFsup()

    def test_case1(self):
        """Testing the initalize population function - size of 10"""

        pop = self.geneticAlgorithm.initializePopulation(10)
        result = True

        for sol in pop:
            if not (isinstance(sol, Solution)):
                result = False

        if len(pop) != 10:
            result = False

        self.assertTrue(result)

    def test_case2(self):
        """Testing the fast non-dominated sort function"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        fronts = self.geneticAlgorithm.fast_non_dominated_sort(pop)

        expectedFront0 = [pop[5]]
        expectedFront1 = [pop[3], pop[4]]
        expectedFront2 = [pop[0], pop[2], pop[6]]
        expectedFront3 = [pop[1]]

        expected = [
            expectedFront0, expectedFront1, expectedFront2, expectedFront3
        ]

        result = True

        for i in range(len(expected)):
            for sol in expected[i]:
                if sol not in fronts[i]:
                    result = False

        self.assertTrue(result)

    def test_case3(self):
        """Testing the crowding distance assignment"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        maxFst = max(pop, key=lambda x: x.getFst()).getFst()
        minFst = min(pop, key=lambda x: x.getFst()).getFst()

        maxFsup = max(pop, key=lambda x: x.getFsup()).getFsup()
        minFsup = min(pop, key=lambda x: x.getFsup()).getFsup()

        self.geneticAlgorithm.crowding_distance_assignment(
            pop, maxFst, minFst, maxFsup, minFsup)

        expected = [
            float("inf"), 0.9, 0.375, 0.975,
            float("inf"),
            float("inf"), 0.525
        ]

        result = [round(sol.crowdingDistance, 5) for sol in pop]

        self.assertEqual(result, expected)

    def test_case4(self):
        """Testing the crowding distance assignment function - when only 1 element in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        maxFst = max(pop, key=lambda x: x.getFst()).getFst()
        minFst = min(pop, key=lambda x: x.getFst()).getFst()

        maxFsup = max(pop, key=lambda x: x.getFsup()).getFsup()
        minFsup = min(pop, key=lambda x: x.getFsup()).getFsup()

        self.geneticAlgorithm.crowding_distance_assignment([pop[0]], maxFst,
                                                           minFst, maxFsup,
                                                           minFsup)

        expected = [float("inf")]

        result = [round(sol.crowdingDistance, 5) for sol in [pop[0]]]

        self.assertEqual(result, expected)

    def test_case5(self):
        """Testing the crowding distance assignment function - when only 2 element in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        maxFst = max(pop, key=lambda x: x.getFst()).getFst()
        minFst = min(pop, key=lambda x: x.getFst()).getFst()

        maxFsup = max(pop, key=lambda x: x.getFsup()).getFsup()
        minFsup = min(pop, key=lambda x: x.getFsup()).getFsup()

        self.geneticAlgorithm.crowding_distance_assignment(
            pop[0:2], maxFst, minFst, maxFsup, minFsup)

        expected = [float("inf"), float("inf")]

        result = [round(sol.crowdingDistance, 5) for sol in pop[0:2]]

        self.assertEqual(result, expected)

    def test_case6(self):
        """Testing the crowding distance assignment function - when only 3 element in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        maxFst = max(pop, key=lambda x: x.getFst()).getFst()
        minFst = min(pop, key=lambda x: x.getFst()).getFst()

        maxFsup = max(pop, key=lambda x: x.getFsup()).getFsup()
        minFsup = min(pop, key=lambda x: x.getFsup()).getFsup()

        self.geneticAlgorithm.crowding_distance_assignment(
            pop[0:3], maxFst, minFst, maxFsup, minFsup)

        expected = [float("inf"), float("inf"), float("inf")]

        result = [round(sol.crowdingDistance, 5) for sol in pop[0:3]]

        self.assertEqual(result, expected)

    def test_case7(self):
        """Testing the crowding distance assignment function - when only 4 element in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        maxFst = max(pop, key=lambda x: x.getFst()).getFst()
        minFst = min(pop, key=lambda x: x.getFst()).getFst()

        maxFsup = max(pop, key=lambda x: x.getFsup()).getFsup()
        minFsup = min(pop, key=lambda x: x.getFsup()).getFsup()

        self.geneticAlgorithm.crowding_distance_assignment(
            pop[0:4], maxFst, minFst, maxFsup, minFsup)

        expected = [float("inf"), float("inf"), 0.9, float("inf")]

        result = [round(sol.crowdingDistance, 5) for sol in pop[0:4]]

        self.assertEqual(result, expected)

    def test_case8(self):
        """Tesitng make new Population function"""

        fronts = self.geneticAlgorithm.fast_non_dominated_sort(self.population)
        self.geneticAlgorithm.crowding_distance_assignment(
            self.population, self.maxFst, self.minFst, self.maxFsup,
            self.minFsup)

        newPop = self.geneticAlgorithm.makeNewPopulation(
            self.population, self.populationSize, self.mutationProbability,
            self.swapProbability, self.transferProbability)

        result = True

        for sol in newPop:
            if not (isinstance(sol, Solution)):
                result = False

        if len(newPop) != ((self.populationSize) + (self.populationSize // 2)):
            result = False

        self.assertTrue(result)

    def test_case9(self):
        """Testing the calc Spacing Metric function - when 2 elements in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(2)
        points = [(25, 0.6), (27, 0.2)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        result = calcSpacing(pop)

        self.assertEqual(result, 0)

    def test_case10(self):
        """Testing the calc Spacing Metric function - when multiple elements in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(7)
        points = [(25, 0.6), (27, 0.2), (27, 0.5), (29, 0.8), (30, 0.1),
                  (30, 0.9), (27, 0.5)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        result = calcSpacing(pop)
        expected = 0.683927116

        self.assertAlmostEqual(result, expected, places=5)

    def test_case11(self):
        """Testing the calc Spacing Metric function - when 1 element in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(1)
        points = [(25, 0.6)]

        for i, sol in enumerate(pop):
            sol.setFst(points[i][0])
            sol.setFsup(points[i][1])

        result = calcSpacing(pop)

        self.assertEqual(result, 0)

    def test_case12(self):
        """Testing the calc Spacing Metric function - when 0 elements in frontier"""

        pop = self.geneticAlgorithm.initializePopulation(0)

        result = calcSpacing(pop)

        self.assertEqual(result, 0)
    def setUp(self):

        #Creating a list of students and supervisors

        topicNames, topicPaths, topicIDs, levels = parseFile(
            "pystsup/test/acm.txt")

        self.supervisors = {}
        self.students = {}

        stuID = "student"
        supID = "supervisor"

        stuList1 = [
            "MapReduce-based systems", "Multidimensional range search",
            "Open source software", "Data mining", "Online shopping"
        ]
        stuList2 = [
            "Heuristic function construction", "Multi-agent systems",
            "Open source software", "Data mining", "Speech recognition"
        ]
        stuList3 = [
            "Multi-agent systems", "Speech recognition",
            "Heuristic function construction", "Data mining",
            "Object identification"
        ]
        stuList4 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList1 = [
            "Multi-agent systems", "Intelligent agents",
            "MapReduce-based systems", "Object identification",
            "Heuristic function construction"
        ]
        supList2 = [
            "Open source software", "Data mining", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]
        supList3 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList = [supList1, supList2, supList3]
        supQuota = [2, 2, 1]
        stuList = [stuList1, stuList2, stuList3, stuList4]

        for i in range(3):
            toAdd = []
            sup_list = {}
            rank = 0
            for kw in supList[i]:
                rank += 1
                sup_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            sup = supID + str(i + 1)
            quota = supQuota[i]

            supervisorObject = Supervisor(sup, sup_list, quota)

            self.supervisors[sup] = supervisorObject

        for i in range(4):
            toAdd = []
            stu_list = {}
            rank = 0
            for kw in stuList[i]:
                rank += 1
                stu_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            stu = stuID + str(i + 1)
            studentObject = Student(stu, stu_list)
            self.students[stu] = studentObject

        # Generating rank weights for c = 0.5

        self.rankWeights = Solution.calcRankWeights()

        #Creating fitness cache

        self.dummySolution = Solution()

        self.fitnessCache = {}

        for sup in self.supervisors:
            supervisorKeywords = self.supervisors[sup].getKeywords()
            for stu in self.students:
                studentKeywords = self.students[stu].getKeywords()
                f_stu, f_sup = self.dummySolution.kw_similarity(
                    studentKeywords, supervisorKeywords, self.rankWeights)
                self.fitnessCache[str((stu, sup))] = (f_stu, f_sup)

        # Creating two graphs and solutions

        self.graph1 = BipartiteGraph()
        self.graph2 = BipartiteGraph()

        self.graph1.addEdge("supervisor1", "student2")
        self.graph1.addEdge("supervisor2", "student4")
        self.graph1.addEdge("supervisor3", "student1")
        self.graph1.addEdge("supervisor1", "student3")

        self.solution1 = Solution(self.graph1)

        self.graph2.addEdge("supervisor1", "student2")
        self.graph2.addEdge("supervisor2", "student1")
        self.graph2.addEdge("supervisor3", "student4")
        self.graph2.addEdge("supervisor1", "student3")

        self.solution2 = Solution(self.graph2)
class MutationTest(unittest.TestCase):
    def setUp(self):

        #Creating a list of students and supervisors

        topicNames, topicPaths, topicIDs, levels = parseFile(
            "pystsup/test/acm.txt")

        self.supervisors = {}
        self.students = {}

        stuID = "student"
        supID = "supervisor"

        stuList1 = [
            "MapReduce-based systems", "Multidimensional range search",
            "Open source software", "Data mining", "Online shopping"
        ]
        stuList2 = [
            "Heuristic function construction", "Multi-agent systems",
            "Open source software", "Data mining", "Speech recognition"
        ]
        stuList3 = [
            "Multi-agent systems", "Speech recognition",
            "Heuristic function construction", "Data mining",
            "Object identification"
        ]
        stuList4 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList1 = [
            "Multi-agent systems", "Intelligent agents",
            "MapReduce-based systems", "Object identification",
            "Heuristic function construction"
        ]
        supList2 = [
            "Open source software", "Data mining", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]
        supList3 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList = [supList1, supList2, supList3]
        supQuota = [2, 2, 1]
        stuList = [stuList1, stuList2, stuList3, stuList4]

        for i in range(3):
            toAdd = []
            sup_list = {}
            rank = 0
            for kw in supList[i]:
                rank += 1
                sup_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            sup = supID + str(i + 1)
            quota = supQuota[i]

            supervisorObject = Supervisor(sup, sup_list, quota)

            self.supervisors[sup] = supervisorObject

        for i in range(4):
            toAdd = []
            stu_list = {}
            rank = 0
            for kw in stuList[i]:
                rank += 1
                stu_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            stu = stuID + str(i + 1)
            studentObject = Student(stu, stu_list)
            self.students[stu] = studentObject

        # Generating rank weights for c = 0.5

        self.rankWeights = Solution.calcRankWeights()

        #Creating fitness cache

        self.dummySolution = Solution()

        self.fitnessCache = {}

        for sup in self.supervisors:
            supervisorKeywords = self.supervisors[sup].getKeywords()
            for stu in self.students:
                studentKeywords = self.students[stu].getKeywords()
                f_stu, f_sup = self.dummySolution.kw_similarity(
                    studentKeywords, supervisorKeywords, self.rankWeights)
                self.fitnessCache[str((stu, sup))] = (f_stu, f_sup)

        # Creating two graphs and solutions

        self.graph1 = BipartiteGraph()
        self.graph2 = BipartiteGraph()

        self.graph1.addEdge("supervisor1", "student2")
        self.graph1.addEdge("supervisor2", "student4")
        self.graph1.addEdge("supervisor3", "student1")
        self.graph1.addEdge("supervisor1", "student3")

        self.solution1 = Solution(self.graph1)

        self.graph2.addEdge("supervisor1", "student2")
        self.graph2.addEdge("supervisor2", "student1")
        self.graph2.addEdge("supervisor3", "student4")
        self.graph2.addEdge("supervisor1", "student3")

        self.solution2 = Solution(self.graph2)

    def test_case1(self):
        """Testing mutation function for solution 1"""
        mutationProbability = 0.3
        swapProbability = 0.5
        transferProbability = 0.5
        solution3 = mutate(self.solution1, self.supervisors,
                           mutationProbability, swapProbability,
                           transferProbability)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case2(self):
        """Testing mutation function for solution 1 - only swap operation"""
        mutationProbability = 0.3
        swapProbability = 0.5
        transferProbability = 0
        solution3 = mutate(self.solution1, self.supervisors,
                           mutationProbability, swapProbability,
                           transferProbability)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case3(self):
        """Testing mutation function for solution 1 - only transfer operation"""
        mutationProbability = 0.3
        swapProbability = 0
        transferProbability = 0.5
        solution3 = mutate(self.solution1, self.supervisors,
                           mutationProbability, swapProbability,
                           transferProbability)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case4(self):
        """Testing mutation function for solution 2"""
        mutationProbability = 0.3
        swapProbability = 0.5
        transferProbability = 0.3
        solution4 = mutate(self.solution2, self.supervisors,
                           mutationProbability, swapProbability,
                           transferProbability)

        result = solution4.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case5(self):
        """Testing mutation function for a randomly created solution 1"""

        mutationProbability = 0.3
        swapProbability = 0.2
        transferProbability = 0.8

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution2 = mutate(solution1, self.supervisors, mutationProbability,
                           swapProbability, transferProbability)

        result = solution2.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case6(self):
        """Testing mutation function for a randomly created solution 2"""

        mutationProbability = 0.3
        swapProbability = 0.7
        transferProbability = 0

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution2 = mutate(solution1, self.supervisors, mutationProbability,
                           swapProbability, transferProbability)

        result = solution2.isValid(self.students, self.supervisors)

        self.assertTrue(result)
    def test_case28(self):
        """Testing 'dominates' function - when only Fst is greater in solution2 and solution1"""

        solution1 = Solution()
        solution2 = Solution()

        solution1.setFst(26.5)
        solution1.setFsup(0.4)

        solution2.setFst(27.5)
        solution2.setFsup(0.2)

        result = solution1.dominates(solution2)

        self.assertFalse(result)
def mutate(solution, supervisors, probability, swapProbability,
           transferProbability):
    """
        Function to perform the mutation operator on a solution.

        Parameters:

            solution (Solution) - the solution we want to mutate.
            supervisors (dictionary) - dictionary of all supervisors with their details (id,preferences,quota)
            probability (float) - the probability of mutating an edge.
            swapProbability (float) - the probability of doing a swap on a mutating edge.
            transferProbability (float) - the probability of doing a transfer on a mutating edge.

        Returns:

            newSolutions (list) - list of mutated solutions. Same size as the given population.
        """

    #Make a copy of the solution graph
    graph = solution.getGraph().copy()

    #Get the list of supervisors to and from whom we can transfer
    canTransferFrom, canTransferTo = solution.getTransferable(supervisors)

    supEdges = copy.deepcopy(graph.getEdges())
    stuEdges = copy.deepcopy(graph.getStuEdges())

    allStudents = set(list(stuEdges.keys()))
    allSupervisors = set(list(supEdges.keys()))

    probSum = swapProbability + transferProbability
    swapProbability = swapProbability / probSum
    transferProbability = transferProbability / probSum

    count = 0

    for sup in supEdges:

        for stu in supEdges[sup]:

            if graph.isEdge(sup, stu):

                n = random.random()

                if n <= probability:

                    count += 1

                    m = random.random()

                    if m <= transferProbability and (
                            graph.getSupervisorDegree(sup) > 1
                    ) and not (len(canTransferTo) == 1 and
                               (sup
                                in canTransferTo)) and len(canTransferTo) > 0:
                        #Perform Transfer Operation

                        if sup in canTransferTo:
                            canTransferTo.remove(sup)

                        toSup = random.choice(list(canTransferTo))

                        graph.transferStudent1(stu, sup, toSup, supervisors)

                        canTransferTo.add(sup)

                        if not (graph.getSupervisorDegree(toSup) <
                                supervisors[toSup].getQuota()):
                            canTransferTo.remove(toSup)

                    else:

                        #Peform Swap Operation

                        allSupervisors.remove(sup)

                        sup2 = random.choice(list(allSupervisors))

                        stu2 = random.choice(graph.getStudents(sup2))

                        graph.swapStudents(stu, sup, stu2, sup2)

                        allSupervisors.add(sup)

    return Solution(graph)
    def test_case29(self):
        """Testing 'dominates' function - when both Fst and Fsup are lesser in solution1 than solution2"""

        solution1 = Solution()
        solution2 = Solution()

        solution1.setFst(26.5)
        solution1.setFsup(0.2)

        solution2.setFst(27.5)
        solution2.setFsup(0.4)

        result = solution1.dominates(solution2)

        self.assertFalse(result)
    def test_case32(self):
        """Testing 'dominates' function - when Fst and Fsup are same in solution2 and solution1"""

        solution1 = Solution()
        solution2 = Solution()

        solution1.setFst(29.5)
        solution1.setFsup(0.4)

        solution2.setFst(29.5)
        solution2.setFsup(0.4)

        result = solution1.dominates(solution2)

        self.assertFalse(result)
示例#30
0
class CrossoverTest(unittest.TestCase):
    def setUp(self):

        #Creating a list of students and supervisors

        topicNames, topicPaths, topicIDs, levels = parseFile(
            "pystsup/test/acm.txt")

        self.supervisors = {}
        self.students = {}

        stuID = "student"
        supID = "supervisor"

        stuList1 = [
            "MapReduce-based systems", "Multidimensional range search",
            "Open source software", "Data mining", "Online shopping"
        ]
        stuList2 = [
            "Heuristic function construction", "Multi-agent systems",
            "Open source software", "Data mining", "Speech recognition"
        ]
        stuList3 = [
            "Multi-agent systems", "Speech recognition",
            "Heuristic function construction", "Data mining",
            "Object identification"
        ]
        stuList4 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList1 = [
            "Multi-agent systems", "Intelligent agents",
            "MapReduce-based systems", "Object identification",
            "Heuristic function construction"
        ]
        supList2 = [
            "Open source software", "Data mining", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]
        supList3 = [
            "Multi-agent systems", "Intelligent agents", "Speech recognition",
            "Object identification", "Heuristic function construction"
        ]

        supList = [supList1, supList2, supList3]
        supQuota = [2, 2, 1]
        stuList = [stuList1, stuList2, stuList3, stuList4]

        for i in range(3):
            toAdd = []
            sup_list = {}
            rank = 0
            for kw in supList[i]:
                rank += 1
                sup_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            sup = supID + str(i + 1)
            quota = supQuota[i]

            supervisorObject = Supervisor(sup, sup_list, quota)

            self.supervisors[sup] = supervisorObject

        for i in range(4):
            toAdd = []
            stu_list = {}
            rank = 0
            for kw in stuList[i]:
                rank += 1
                stu_list[rank] = [
                    kw, getPath(kw, topicNames, topicPaths, topicIDs)
                ]

            stu = stuID + str(i + 1)
            studentObject = Student(stu, stu_list)
            self.students[stu] = studentObject

        # Generating rank weights for c = 0.5

        self.rankWeights = Solution.calcRankWeights()

        #Creating fitness cache

        self.dummySolution = Solution()

        self.fitnessCache = {}

        for sup in self.supervisors:
            supervisorKeywords = self.supervisors[sup].getKeywords()
            for stu in self.students:
                studentKeywords = self.students[stu].getKeywords()
                f_stu, f_sup = self.dummySolution.kw_similarity(
                    studentKeywords, supervisorKeywords, self.rankWeights)
                self.fitnessCache[str((stu, sup))] = (f_stu, f_sup)

        # Creating two graphs and solutions

        self.graph1 = BipartiteGraph()
        self.graph2 = BipartiteGraph()

        self.graph1.addEdge("supervisor1", "student2")
        self.graph1.addEdge("supervisor2", "student4")
        self.graph1.addEdge("supervisor3", "student1")
        self.graph1.addEdge("supervisor1", "student3")

        self.solution1 = Solution(self.graph1)

        self.graph2.addEdge("supervisor1", "student2")
        self.graph2.addEdge("supervisor2", "student1")
        self.graph2.addEdge("supervisor3", "student4")
        self.graph2.addEdge("supervisor1", "student3")

        self.solution2 = Solution(self.graph2)

        # Creating test for simplify function
        self.graph3 = BipartiteGraph()
        self.graph3.addEdge("s1", "st1")
        self.graph3.addEdge("s1", "st4")
        self.graph3.addEdge("s2", "st1")
        self.graph3.addEdge("s2", "st2")
        self.graph3.addEdge("s3", "st3")
        self.graph3.addEdge("s3", "st5")
        self.graph3.addEdge("s4", "st3")
        self.graph3.addEdge("s4", "st5")
        self.structure3 = {"s1": 2, "s2": 1, "s3": 1, "s4": 1}

        self.graph4 = BipartiteGraph()
        self.graph4.addEdge("s1", "st1")
        self.graph4.addEdge("s1", "st3")
        self.graph4.addEdge("s1", "st4")
        self.graph4.addEdge("s2", "st3")
        self.graph4.addEdge("s2", "st4")
        self.graph4.addEdge("s3", "st1")
        self.graph4.addEdge("s3", "st2")
        self.structure4 = {"s1": 1, "s2": 2, "s3": 1}

        #Creating 60-400 data set

        self.students2, self.supervisors2 = createRandomData(60, 400, 405)
        # m,n,quotaSum,level=3,maxQuota=10,minQuota=4,no_topics=5
        self.students3, self.supervisors3 = createRandomData(3,
                                                             5,
                                                             8,
                                                             minQuota=1,
                                                             maxQuota=3)
        self.problem_instances = [  #createRandomData(6,10,16,minQuota=1) 
            createRandomData(60, 400, 405)
        ]

        #def test_case_special_cr(self):
        #for (students,supervisors) in self.problem_instances :
        #for i in range(100):
        #   sol1 = Solution.generateRandomSolution(students,supervisors)
        #   sol2 = Solution.generateRandomSolution(students,supervisors)
        #   sp_crossover(sol1,sol2)

    def test_case_simplify1(self):
        response, already_set = simplify(self.graph3, self.structure3)
        self.assertTrue(("s1", "st1") in response)
        self.assertTrue(("s1", "st4") in response)
        self.assertTrue(("s2", "st2") in response)
        self.assertEqual(self.structure3["s1"], 0)
        self.assertEqual(self.structure3["s2"], 0)
        self.assertEqual(self.structure3["s3"], 1)
        self.assertEqual(self.structure3["s4"], 1)
        self.assertTrue(("stu", "st1") in already_set)
        self.assertTrue(("stu", "st4") in already_set)
        self.assertTrue(("stu", "st2") in already_set)
        self.assertTrue(("sup", "s1") in already_set)
        self.assertTrue(("sup", "s2") in already_set)
        self.assertEqual(len(response), 3)

    def test_case_simplify2(self):
        response, already_set = simplify(self.graph4, self.structure4)
        self.assertTrue(("s1", "st1") in response)
        self.assertTrue(("s2", "st3") in response)
        self.assertTrue(("s2", "st4") in response)
        self.assertTrue(("s3", "st2") in response)
        self.assertEqual(self.structure4["s1"], 0)
        self.assertEqual(self.structure4["s2"], 0)
        self.assertEqual(self.structure4["s3"], 0)
        self.assertTrue(("stu", "st1") in already_set)
        self.assertTrue(("stu", "st3") in already_set)
        self.assertTrue(("stu", "st4") in already_set)
        self.assertTrue(("stu", "st2") in already_set)
        self.assertTrue(("sup", "s1") in already_set)
        self.assertTrue(("sup", "s2") in already_set)
        self.assertTrue(("sup", "s3") in already_set)
        self.assertEqual(len(response), 4)

    def test_case1(self):
        """Testing the ERX Modified Crossover function - for 3sup:4stu solution"""

        solution3 = crossover(self.solution1, self.solution2, self.supervisors,
                              self.students)

        structureResult = (solution3.getGraph().getStructure()
                           == self.solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == self.solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students,
                                    self.supervisors)) and (structureResult)

        self.assertTrue(result)

    def test_case2(self):
        """Testing the kPoint crossover function - for 3sup:4stu solution"""

        solution3 = kPoint(self.solution1,
                           self.solution2,
                           self.supervisors,
                           self.students,
                           k=3)
        result = solution3.isValid(self.students, self.supervisors)
        self.assertTrue(result)

    def test_case3(self):
        """Testing the EDX Modified crossover function - when one valid and one dummy solution are passed"""

        self.assertRaises(
            KeyError, lambda: crossover(self.solution1, self.dummySolution,
                                        self.supervisors, self.students))

    def test_case4(self):
        """Testing the K Point Crossover function - when one valid and one dummy solution are passed"""

        self.assertRaises(
            KeyError, lambda: kPoint(self.solution2,
                                     self.dummySolution,
                                     self.supervisors,
                                     self.students,
                                     k=3))

    def test_case5(self):
        """Testing the ERX Modified Crossover function - for random 3sup:4stu solution"""

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)
        solution2 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution3 = crossover(solution1, solution2, self.supervisors,
                              self.students)

        structureResult = (solution3.getGraph().getStructure()
                           == solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students,
                                    self.supervisors)) and (structureResult)

        self.assertTrue(result)

    def test_case6(self):
        """Testing the K Point Crossover function - for random 3sup:4stu solution"""

        solution1 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)
        solution2 = Solution.generateRandomSolution(self.students,
                                                    self.supervisors)

        solution3 = kPoint(solution1,
                           solution2,
                           self.supervisors,
                           self.students,
                           k=3)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case7(self):
        """Testing the K Point crossover function - when k=0"""

        solution3 = kPoint(self.solution1,
                           self.solution2,
                           self.supervisors,
                           self.students,
                           k=0)

        structureResult = (solution3.getGraph().getStructure()
                           == self.solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == self.solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students,
                                    self.supervisors)) and (structureResult)

        self.assertTrue(result)

    def test_case8(self):
        """Testing the K Point crossover function - when k=1"""

        solution3 = kPoint(self.solution1,
                           self.solution2,
                           self.supervisors,
                           self.students,
                           k=1)

        result = solution3.isValid(self.students, self.supervisors)

        self.assertTrue(result)

    def test_case9(self):
        """Testing the K Point crossover function - when k > no_students"""

        self.assertRaises(
            ValueError, lambda: kPoint(self.solution1,
                                       self.solution2,
                                       self.supervisors,
                                       self.students,
                                       k=6))

    def test_case10(self):
        """Testing the ERX Modified crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = crossover(solution1, solution2, self.supervisors2,
                              self.students2)

        structureResult = (solution3.getGraph().getStructure()
                           == solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students2,
                                    self.supervisors2)) and (structureResult)

        self.assertTrue(result)

    def test_case11(self):
        """Testing the ERX Modified crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = crossover(solution1, solution2, self.supervisors,
                              self.supervisors2, self.students2)

        structureResult = (solution3.getGraph().getStructure()
                           == solution1.getGraph().getStructure()) or (
                               solution3.getGraph().getStructure()
                               == solution2.getGraph().getStructure())
        result = (solution3.isValid(self.students2,
                                    self.supervisors2)) and (structureResult)

        self.assertTrue(result)

    def test_case12(self):
        """Testing the kPoint crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = kPoint(solution1,
                           solution2,
                           self.supervisors2,
                           self.students2,
                           k=15)

        result = solution3.isValid(self.students2, self.supervisors2)

        self.assertTrue(result)

    def test_case13(self):
        """Testing the kPoint crossover function - for random 60sup:400stu solution"""

        solution1 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)
        solution2 = Solution.generateRandomSolution(self.students2,
                                                    self.supervisors2)

        solution3 = kPoint(solution1,
                           solution2,
                           self.supervisors2,
                           self.students2,
                           k=15)

        result = solution3.isValid(self.students2, self.supervisors2)

        self.assertTrue(result)