diff --git a/Genetic Algorithm2.py b/Genetic Algorithm2.py new file mode 100644 index 0000000..713ba01 --- /dev/null +++ b/Genetic Algorithm2.py @@ -0,0 +1,236 @@ +from collections import deque +import secrets +from random import randrange +from random import random + +import math + +global unitCounts +global intervalCounts + +global unitArray +unitArray = [] + +global intervalsArray +intervalsArray = [] + +def readFilesAndCreateObjects(): + secondFile = open("second.txt", 'rt') + lines = secondFile.read().split('\n') + intervalCounts = int(lines.pop(0)) + for line in lines: + res = line.split(',') + intervalsArray.append(Interval(res[0], res[1])) + secondFile.close() + + firstFile = open("first.txt", "rt") + lines = firstFile.read().split('\n') + unitCounts = int(lines.pop(0)) + for line in lines: + res = line.split(',') + unitArray.append(Unit(res[0], res[1], res[2], intervalCounts)) + firstFile.close() + + +class Unit: + def __init__(self, id, capacity, repairCount,intervalsCount): + self.unitID = int(id) + self.unitCapacity = int(capacity) + self.unitRepairCount = int(repairCount) + self.unitPools = self.genreatePools(self.unitRepairCount,intervalsCount) + + def genreatePools(self,reapirCount,intervals): + pools = [] + tempArray = [] + for x in range(reapirCount): + tempArray.append(1) + for x in range(intervals-reapirCount): + tempArray.append(0) + + pools.append(tempArray) + items = deque(tempArray) + for x in range(intervals-reapirCount): + items.rotate(1) + pools.append(list(items)) + # print(pools) + return pools + + +class Interval: + def __init__(self, id, demand): + self.intervalID = int(id) + self.intervalDemand = int(demand) + +class Population: + def __init__(self,size,initialize): + self.size = size + self.individulas = [None] * size + if initialize=='true': + for i in range(size): + indiv = generateIndividual() + self.individulas[i] = indiv + self.saveIndividual(i,indiv) + + def saveIndividual(self,index,indiv): + self.individulas[index] = indiv + + def getIndividual(self,i): + return self.individulas[i] + + # tested + def getFittestInPop(self): + fittest = self.individulas[0] + for i in range(len(self.individulas)): + if self.findMinimumIntervalCapacityInOrders(fittest) <= self.findMinimumIntervalCapacityInOrders(self.individulas[i]): + fittest = self.individulas[i] + return fittest + + def getFittestFitnessRate(self): + fit = self.getFittestInPop() + return self.findMinimumIntervalCapacityInOrders(fit) + + # tested + def findMinimumIntervalCapacityInOrders(self,orderList): + minimumInterval = -1 + minimum = self.calcIntervalExtraCapacity(orderList, 0) + minimumIntervalsList = [] + for intervalIndex in range(len(intervalsArray)): + extraCapacity = self.calcIntervalExtraCapacity(orderList, intervalIndex) + if extraCapacity < minimum: + minimum = extraCapacity + minimumInterval = intervalIndex + minimumIntervalsList = [] + elif extraCapacity == minimum: + minimumIntervalsList.append(intervalIndex) + if len(minimumIntervalsList) != 0: + if minimumInterval > -1: + minimumIntervalsList.append(minimumInterval) + minimumInterval = secrets.choice(minimumIntervalsList) + minimumIntervalsList = [] + # return minimumInterval + return self.calcIntervalExtraCapacity(orderList, minimumInterval) + + # tested + def calcIntervalExtraCapacity(self,orderList: [], intervalIndex: int): + sum = 0 + for unitIndex in range(len(unitArray)): + if orderList[unitIndex][intervalIndex] == 0: + sum = sum + unitArray[unitIndex].unitCapacity + return sum - intervalsArray[intervalIndex].intervalDemand + + # for test + def calcAllNeededInOrders(self,orderList): + neededCapcacity = 0 + for index in range(len(intervalsArray)): + extraCapacity = self.calcIntervalExtraCapacity(orderList, index) + if extraCapacity < 0: + neededCapcacity = neededCapcacity + extraCapacity + print(str(index) + " & Extra Capacity is " + str( + (self.calcIntervalExtraCapacity(orderList, index)))) + return neededCapcacity ## # + + + +class Algorithm: + def __init__(self,uniformRate,mutationRate,tournamentSize,elitism): + self.uniformRate = uniformRate + self.mutationRate = mutationRate + self.tournamentSize = tournamentSize + self.elitism = elitism + + def evelopePopulation(self,pop:Population): + newPopulation = Population(pop.size,'false') + + # keep the best + if self.elitism == 'true': + newPopulation.saveIndividual(0,pop.getFittestInPop()) + + # crossover Population + if self.elitism=='true': + self.elitismOffset = 1 + else : + self.elitismOffset = 0; + + # crossover + # tested + for i in range(self.elitismOffset,pop.size,1): + indiv1 = self.tournamentSelection(pop) + indiv2 = self.tournamentSelection(pop) + newIndiv = self.crossover(indiv1,indiv2) + newPopulation.saveIndividual(i,newIndiv) + + # mutate + # tested + for i in range(self.elitismOffset,pop.size,1): + mutatedIndiv = self.mutate(newPopulation.getIndividual(i)) + newPopulation.saveIndividual(i,mutatedIndiv) + + return newPopulation + + # tested + def crossover(self,indiv1,indiv2): + newIndiv = [None] * len(indiv1) + for i in range(len(indiv1)): + if random() <= self.uniformRate: + newIndiv[i] = indiv1[i] + else: + newIndiv[i] = indiv2[i] + return newIndiv + + # tested + def mutate(self,indiv): + for i in range(len(indiv)): + if random() <= self.mutationRate: + randomGenePoll = secrets.choice(unitArray[i].unitPools) + indiv[i] = randomGenePoll + return indiv + + def tournamentSelection(self,pop:Population): + tournomentPop = Population(self.tournamentSize,'false') + for i in range(self.tournamentSize): + randomID = randrange(pop.size) + tournomentPop.saveIndividual(i,pop.getIndividual(randomID)) + + fittest = tournomentPop.getFittestInPop() + return fittest + + + +def generateIndividual(): + individual = [] + for unit in unitArray: + individual.append(secrets.choice(unit.unitPools)) + return individual + +def printIndividuals(indivLists:list): + for i in indivLists: + print(i) + + +def printPop(pop:Population,number): + print('pop test' + str(number)) + for i in range(len(pop.individulas)): + print('indiv' + str(i)) + print(pop.calcAllNeededInOrders(pop.individulas[i])) + print() + +def main() : + readFilesAndCreateObjects() + pop = Population(10,'true') + algorithm = Algorithm(0.7,0.5,4,'true') + newPop = algorithm.evelopePopulation(pop) + generationCount = 100 + for generationIndex in range(generationCount): + if pop.getFittestFitnessRate() <= newPop.getFittestFitnessRate(): + print("generation: "+ str(generationIndex) + " fittest: " + str(newPop.getFittestFitnessRate())) + pop = newPop + newPop = algorithm.evelopePopulation(pop) + + print() + print('answer is') + fittest = pop.getFittestInPop() + print(fittest) + print(pop.calcAllNeededInOrders(fittest)) + print("fittest fitness is: " + str(pop.getFittestFitnessRate())) + +main() diff --git a/SimulatedAnealing.py b/SimulatedAnealing.py index 9c4d8a6..cd5a68d 100644 --- a/SimulatedAnealing.py +++ b/SimulatedAnealing.py @@ -12,9 +12,6 @@ global intervalsArray intervalsArray = [] -global orderList -orderList = [] - class Unit: def __init__(self, id, capacity, repairCount,intervalsCount): self.unitID = int(id) @@ -44,11 +41,10 @@ def __init__(self, id, demand): self.intervalID = int(id) self.intervalDemand = int(demand) -class solution: - def __init__(self,orderList:list,demand:int): +class Solution: + def __init__(self,orderList:list,minimumExtraCapacity:int): self.orderList = orderList - self.demand = demand - + self.minimumExtraCapacity = minimumExtraCapacity def readFilesAndCreateObjects(): secondFile = open("second.txt", 'rt') @@ -67,65 +63,121 @@ def readFilesAndCreateObjects(): unitArray.append(Unit(res[0], res[1], res[2], intervalCounts)) firstFile.close() -def calcIntervalExtraCapacity(orderList:[],intervalIndex:int): +def calcIntervalExtraCapacity(orderList:[], intervalIndex:int): sum = 0 - for index in range(len(unitArray)): - if orderList[index][intervalIndex] == 0 : - sum = sum + unitArray[index].unitCapacity + for unitIndex in range(len(unitArray)): + if orderList[unitIndex][intervalIndex] == 0 : + sum = sum + unitArray[unitIndex].unitCapacity return sum - intervalsArray[intervalIndex].intervalDemand -def acceptanceProbability(currentDemand,neighbourDemand,temp): - if neighbourDemand < currentDemand : +def calcIntervalExactCapacity(orderList:[], intervalIndex:int): + sum = 0 + for unitIndex in range(len(unitArray)): + if orderList[unitIndex][intervalIndex] == 0 : + sum = sum + unitArray[unitIndex].unitCapacity + return sum + +def acceptanceProbability(currentMinimumExtraCapacity,neighbourMinimumExtraCapacity,temp): + if currentMinimumExtraCapacity < neighbourMinimumExtraCapacity : return 1.0 - # print(((neighbourDemand - currentDemand)/temp)) - # return ((neighbourDemand - currentDemand)/temp) - return 0 + print(math.exp((neighbourMinimumExtraCapacity - currentMinimumExtraCapacity)/temp)) + return math.exp((neighbourMinimumExtraCapacity - currentMinimumExtraCapacity)/temp) def fillOrders(): orderList = [] for unit in unitArray: orderList.append(secrets.choice(unit.unitPools)) - print(orderList) return orderList -def calcDemandsInOrders(orderList): - demand = 0 +def calcAllNeededInOrders(orderList): + neededCapcacity = 0 for index in range(len(intervalsArray)): - extraCapacity = calcIntervalExtraCapacity(orderList,index) + extraCapacity = calcIntervalExtraCapacity(orderList, index) if extraCapacity < 0 : - demand = demand + abs(extraCapacity) - print(str(index) + " extra capacity is " + str((calcIntervalExtraCapacity(orderList,index)))) - print(demand) - return demand + neededCapcacity = neededCapcacity + extraCapacity + print(str(index) +" Exact Capacity is "+ str(calcIntervalExactCapacity(orderList, index)) + " & Extra Capacity is " + str((calcIntervalExtraCapacity(orderList, index)))) + return neededCapcacity + +def findMinimumIntervalCapacityInOrders(orderList): + minimumInterval=-1 + minimum = calcIntervalExtraCapacity(orderList, 0) + minimumIntervalsList = [] + for intervalIndex in range(len(intervalsArray)): + extraCapacity = calcIntervalExtraCapacity(orderList, intervalIndex) + if extraCapacity < minimum : + minimum = extraCapacity + minimumInterval = intervalIndex + minimumIntervalsList = [] + elif extraCapacity == minimum : + minimumIntervalsList.append(intervalIndex) + if len(minimumIntervalsList)!=0: + if minimumInterval > -1 : + minimumIntervalsList.append(minimumInterval) + minimumInterval = secrets.choice(minimumIntervalsList) + minimumIntervalsList = [] + return minimumInterval + +def findNeighbourOrderList(orderList,minimumInterval): + newOrderList = orderList.copy() + disabledUnits= [] + for unitIndex in range(len(newOrderList)): + if newOrderList[unitIndex][minimumInterval] == 1: + disabledUnits.append(unitIndex) + selectableUnitPools=[] + selectedUnit = secrets.choice(disabledUnits) + + if selectedUnit: + for unitPool in unitArray[selectedUnit].unitPools: + if unitPool[minimumInterval] == 0: + selectableUnitPools.append(unitPool) + if len(selectableUnitPools)!=0: + selectedUnitPool = secrets.choice(selectableUnitPools) + newOrderList[selectedUnit] = selectedUnitPool + newMinimumInterval = findMinimumIntervalCapacityInOrders(newOrderList); + minimumValue = calcIntervalExtraCapacity(newOrderList, newMinimumInterval) + + solution = Solution(newOrderList,minimumValue) + return solution def main() : readFilesAndCreateObjects() - - global demand orderList = fillOrders() - demand = calcDemandsInOrders(orderList) + minimumInterval = findMinimumIntervalCapacityInOrders(orderList) + minimumValue = calcIntervalExtraCapacity(orderList, minimumInterval) global currentSolution - currentSolution = solution(orderList,demand) + global bestSolution + currentSolution = Solution(orderList,minimumValue) + bestSolution = currentSolution + print(currentSolution.orderList) + print("all needed " + str(calcAllNeededInOrders(currentSolution.orderList))) + print() temp = 1000 - colingRate = 1 + colingRate = 10 while(temp > 1 ): - orderList = fillOrders() - demand = calcDemandsInOrders(orderList) - newSolution = solution(orderList,demand) - if acceptanceProbability(currentSolution.demand,newSolution.demand,temp) > random(): + minimumInterval = findMinimumIntervalCapacityInOrders(currentSolution.orderList); + newSolution = findNeighbourOrderList(currentSolution.orderList,minimumInterval) + print(newSolution.orderList) + print("all needed " + str(calcAllNeededInOrders(newSolution.orderList))) + print("Minimum Extra is " + str(newSolution.minimumExtraCapacity)) + if acceptanceProbability(currentSolution.minimumExtraCapacity,newSolution.minimumExtraCapacity,temp) > random(): print('true') currentSolution = newSolution + if bestSolution.minimumExtraCapacity < newSolution.minimumExtraCapacity: + bestSolution = newSolution + + print() temp = temp - colingRate - # soooo this is solution + # so this is answer solution print() print("answer is") - print(currentSolution.orderList) - print(calcDemandsInOrders(currentSolution.orderList)) - print("deamnd is " + str(currentSolution.demand)) + print(bestSolution.orderList) + print("all needed " + str(calcAllNeededInOrders(bestSolution.orderList))) + print("Minimum Extra is " + str(bestSolution.minimumExtraCapacity)) + main() \ No newline at end of file diff --git a/first.txt b/first.txt index e84c0be..12d34ab 100644 --- a/first.txt +++ b/first.txt @@ -1,6 +1,8 @@ -5 -1,50,1 -2,150,4 -3,90,4 -4,90,3 -4,100,5 \ No newline at end of file +7 +1,50,2 +2,150,3 +3,120,4 +4,96,5 +5,158,2 +6,150,3 +7,172,4 \ No newline at end of file diff --git a/second.txt b/second.txt index 2942eef..f6c5e03 100644 --- a/second.txt +++ b/second.txt @@ -1,9 +1,9 @@ 8 -1,50 -2,60 +1,540 +2,450 3,250 -4,100 -5,200 +4,400 +5,410 6,200 -7,150 -8,250 \ No newline at end of file +7,300 +8,300 \ No newline at end of file