def mutation(model, env): # get the batteries from the model batteries = model.modelBatteries # get a random battery randomBatteries = (random.randint(0, len(batteries) - 1), random.randint(0, len(batteries) - 1)) batterySendingHouse = batteries[randomBatteries[0]] # set the upperbounds for the houses randomizer setUpperboundBattery1 = len(batterySendingHouse.houses) # get a random house randomHouseId = random.randint(0, (setUpperboundBattery1 - 1)) # get the houses on the random places house1 = batterySendingHouse.houses[randomHouseId] # get battery receiving the house batteryReceivingHouse = batteries[randomBatteries[1]] # add the house to the other battery batteries[randomBatteries[1]].houses.append(house1) houses = batterySendingHouse.houses houses.pop(randomHouseId) batteries[randomBatteries[0]].houses = houses # return the model returnModel = Model(batteries) returnModel.calculateCosts(env.distanceTable) return returnModel
def makeModel(node, env): # make model to calculate cost of node nodeModelBatteries = env.createModelBatteries() # append each item of node to modelbatteries for i in range(1, len(node)): nodeModelBatteries[node[i] - 1].houses.append(env.houses[i - 1]) # create and return Model nodeModel = Model(nodeModelBatteries) nodeModel.calculateCosts(env.distanceTable) return nodeModel
def randomize(env): modelBatteries = [] # create the array of batteries with the id starting at 1 for i in range(0, len(env.batteries)): maxCap = env.batteries[i].maxCapacity battery = Model.Battery(i + 1) modelBatteries.append(battery) # assign every house to a random battery of which the capacity is still sufficient listOfHouses = env.houses random.shuffle(listOfHouses) # assign random battery to every house for house in listOfHouses: batIndexes = [] for i in range(0, len(env.batteries)): batIndexes.append(i) assignToRandomBattery(batIndexes, env.batteries, house, modelBatteries) # check if every house is connected totalHouses = 0 for battery in modelBatteries: totalHouses += len(battery.houses) if totalHouses == len(env.houses): # assign all the values into a model model = Model(modelBatteries) # calculate the costs of this option model.calculateCosts(env.distanceTable) return model else: return False
def genomeToModel(genome, env): # create the array of batteries with the id starting at 1 modelBatteries = [] for i in range(0, len(env.batteries)): battery = Model.Battery(i + 1) modelBatteries.append(battery) # create child model newModel = Model(modelBatteries) for battery in newModel.modelBatteries: battery.setMaxCapacity(env) # fill list of houses belonging to battery in new model according to genome for gene in genome: for house in env.houses: if house.idHouse == (gene[0]): corHouse = house newModel.modelBatteries[gene[1] - 1].houses.append(corHouse) newModel.calculateCosts(env.distanceTable) return newModel
def depthFirstBnB(env): # create the array of batteries for model modelBatteries = env.createModelBatteries() # initialize algorithm model depthFirstModel = Model(modelBatteries) # initiliaze upperbound at random cost, levels and solution model = runRandom(env) model.calculateCosts(env.distanceTable) upperBound = model.cost levels = len(env.houses) solution = [] # create stack with root houseNode depthFirstStack = [] depthFirstStack.append(np.array([0])) while len(depthFirstStack) > 0: # select last item and pop it node = depthFirstStack.pop() # create array to put best childnode on top of the stack tempCostNodes = [] # create all children lenModelBatteries = len(modelBatteries) for i in range(0, lenModelBatteries): # create new houseNode newNode = np.append(node, modelBatteries[i].idBattery) # check for legit solution if all houses are connected if (len(newNode) - 1) == levels: if checkCapacity(newNode, env.batteries, modelBatteries, env.houses): newModel = makeModel(newNode, env) # set new upperbound for Branch-n-Bound and add solution to list if newModel.cost < upperBound: upperBound = newModel.cost solution = newNode.tolist() # check if there isn't over capacity else: if checkCapacity(newNode, env.batteries, modelBatteries, env.houses): newModel = makeModel(newNode, env) # check if current node isn't already higher than upperbound if newModel.cost < upperBound: tempCostNodes.append([ env.distanceTable[len(newNode) - 1][newNode[-1]], newNode ]) else: continue # childnode with lowest cost on top of the stack tempCostNodes = sorted(tempCostNodes, key=itemgetter(0), reverse=True) tempCostNodes = [node[1] for node in tempCostNodes] depthFirstStack.extend(tempCostNodes) # make depth first model and update battery capacities lenSolution = len(solution) for i in range(1, lenSolution): depthFirstModel.modelBatteries[solution[i] - 1].houses.append( env.houses[i - 1]) depthFirstModel.modelBatteries[solution[i] - 1].curCapacity += env.houses[i - 1].cap depthFirstModel.calculateCosts(env.distanceTable) return depthFirstModel