class SmartHome(Home): def __init__(self, w, h): super().__init__(w, h) self.scenario = Scenario() self.width_bound = [1, w - 1] self.height_bound = [1, h - 1] #self.presence, self.bulbs = self.scenario.diagonal(self.width, self.height) #self.presence, self.bulbs = self.scenario.stripes(self.width, self.height) #self.presence, self.bulbs = self.scenario.corners(self.width, self.height) #self.presence, self.bulbs = self.scenario.corners2(self.width, self.height) self.presence, self.bulbs = self.scenario.extreme( self.width, self.height) self.init_deap() self.init_figures() def generate_individual(self, icls): luminosity = np.zeros((self.height, self.width)) for y in range(self.height_bound[0], self.height_bound[1]): for x in range(self.width_bound[0], self.width_bound[1]): luminosity[y, x] = random.choice([0, 1]) #print ('mutating') genome = self.encode(luminosity) return icls(genome) def init_deap(self): creator.create("FitnessMax", base.Fitness, weights=(1.0, )) creator.create("Individual", list, fitness=creator.FitnessMax) self.steps = 0 self.MAX_STEPS = 500 self.toolbox = base.Toolbox() self.toolbox.register("random_num", random.choice, [0, 1]) self.DIM = self.width * self.height self.toolbox.register( "individual", self.generate_individual, #tools.initRepeat, creator.Individual #self.toolbox.random_num, #n=self.DIM ) print(self.toolbox.individual()) self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) self.toolbox.register("mate", tools.cxTwoPoint) self.toolbox.register("select", tools.selBest) self.toolbox.register("evaluate", self.fitness) self.toolbox.register("mutate", self.mutate) self.pop = self.toolbox.population(n=100) # def fitness_(self, individual, data): # print (data) # print (individual) # match = 0 # #for selected, bulbs in zip(individual, data): # #if selected: # for x in range(self.width): # for y in range(self.height): # if self.presence[x,y]>0 and individual[x,y]>0: # match += 1 # match_percentage = match / self.width * self.height # return match_percentage # def fitness(self, individual):#evalInd4 # score = 0 # #for selected, bulbs in zip(individual, data): # #if selected: # for y in range(self.height): # top left is (X=0,Y=0) # for x in range(self.width): # # if individual[y*self.width+x]>0: # #if self.presence_in_radius(1, x, y): # presence_score = self.presence_in_radius2(1, x, y, individual) # if self.bulbs[x,y] > -1 and presence_score > 0: # score += presence_score # else: # score -= 1 #penalty for using a broken bulb # return (float(score),) def fitness(self, individual): #evalInd4 score = 0 #for selected, bulbs in zip(individual, data): #if selected: for y in range(self.height): # top left is (X=0,Y=0) for x in range(self.width): if individual[y * self.width + x] > 0: #if self.presence_in_radius(1, x, y): presence_score = self.presence_in_radius2( 1, x, y, individual) if self.bulbs[y, x] > -1 and presence_score > 0: score += presence_score else: score -= 1 #penalty for using a broken bulb return (float(score), ) def presence_in_radius2(self, radius, x, y, individual): block = ((y - 1, x - 1), (y, x - 1), (y + 1, x - 1), (y + 1, x), (y + 1, x + 1), (y, x + 1), (y - 1, x + 1), (y - 1, x) ) # starts from left top presence_score = 0 if self.presence[y, x] > 0: presence_score += int( self.weight['present'] * self.evaluation_unit) #award for presence under the bulb #print ('+50') for point in block: if point[0] in range(self.height) and point[1] in range( self.width): if self.presence[point[0], point[1]] > 0: #and self.bulbs[point[0],point[1]] < 0: #individual[point[0]*self.width+point[1]] < 1:#someone present in radius and that area is dark presence_score += int(0.30 * self.weight['present'] * self.evaluation_unit) return presence_score def mutate(self, individual): #print('Mutating') luminosity = self.decode(individual) for i in range(self.width): x = random.randint(self.width_bound[0], self.width_bound[1]) y = random.randint(self.height_bound[0], self.height_bound[1]) if (self.bulbs[y, x] > -1): luminosity[y, x] = random.choice([0, 1]) #luminosity = self.encode (luminosity) self.update_individual(individual, luminosity) #for i in range(self.width): # individual[random.randint(0,len(individual)-1)] = random.choice([0,1]) return (individual, ) def update_individual(self, individual, data): for y in range(self.height): for x in range(self.width): individual[y * self.width + x] = data[y, x] def encode(self, luminosity): return luminosity.flatten() def decode(self, individual): bulbs = np.zeros((self.height, self.width)) for y in range(self.height): # top left is (X=0,Y=0) for x in range(self.width): bulbs[y, x] = individual[y * self.width + x] return bulbs #np.reshape(individual, (-1, self.width)) #------------------ simulation loop ---------------- def updatefig(self, *args): algorithms.eaMuPlusLambda( self.pop, self.toolbox, 400, 100, #parents, children 0.5, 0.5, #probabilities 1) #iterations top = sorted(self.pop, key=lambda x: x.fitness.values[0])[-1] fit = top.fitness.values[0] print('generation:{}, best fitness-: {}'.format(self.steps, fit)) #print("TOP:", top) self.luminosity = self.decode(top) #print("DRAW:",self.luminosity) self.im.set_data(self.luminosity) #self.im.set_array(self.luminosity) #self.im.set_facecolors(self.luminosity) self.luminosity_im.set_data( self.luminosity_extrapolate(self.luminosity)) #im.set_cmap("gray") #im.update() self.steps += 1 if self.steps > self.MAX_STEPS: self.ani.event_source.stop() plt.grid() plt.grid() return self.im, self.luminosity_im def luminosity_extrapolate(self, luminosity): #there must some function doing this interpolation? for y in range(self.height_bound[0], self.height_bound[1]): for x in range(self.width_bound[0], self.width_bound[1]): if self.bulbs[y, x] > -1: if luminosity[y, x] > 0: block = ((y - 1, x - 1), (y, x - 1), (y + 1, x - 1), (y + 1, x), (y + 1, x + 1), (y, x + 1), (y - 1, x + 1), (y - 1, x)) for point in block: if point[1] in range( self.width_bound[0], self.width_bound[1]) and point[0] in range( self.height_bound[0], self.height_bound[1]): luminosity[point[0], point[1]] += 0.15 * luminosity[y, x] else: luminosity[y, x] = 0 return luminosity def run(self): self.ani = animation.FuncAnimation(self.fig, self.updatefig, interval=50, blit=True) plt.show()