def ObjectiveFcn(particle, nVars, Stock, Order): """ MATLAB's peaks function -> objective (fitness function) """ res = 0 newOrder = [ shapely.affinity.rotate(shapely.affinity.translate( Order[j], xoff=particle[j * 3], yoff=particle[j * 3 + 1]), particle[j * 3 + 2], origin='centroid') for j in range(len(Order)) ] remaining = Stock #for i in range(0,len(w1)): #for p in newOrder: # remaining = remaining.difference(p) #if(remaining.is_valid==False): # print(remaining.is_valid) # remaining.buffer(0) #if(remaining.is_empty==True): # print("empty=%d"%remaining.is_empty) #remaining.buffer(0) #remaining = remaining.difference(p) unionNewOrder = shapely.ops.cascaded_union(newOrder) # prevent some errors of empty or invalid result remaining = Stock.difference(unionNewOrder) if (remaining.is_valid == False): print(remaining.is_valid) remaining.buffer(0) if (remaining.is_empty == True): remaining.buffer(0) if (unionNewOrder.is_valid == False): unionNewOrder.buffer(0) if (unionNewOrder.is_empty == True): unionNewOrder.buffer(0) outOfStock = unionNewOrder.difference( Stock) # take newOrder out of stock - inverse of remaining if (outOfStock.is_valid == False): print(outOfStock.is_valid) outOfStock.buffer(0) if (outOfStock.is_empty == True): outOfStock.buffer(0) areaSum = sum([newOrder[w].area for w in range(0, len(newOrder))]) overlapArea = areaSum - unionNewOrder.area dist_from_zero = sum([ newOrder[i].area * (newOrder[i].centroid.x + newOrder[i].centroid.y) for i in range(0, len(newOrder)) ]) ch = (remaining.convex_hull) lamda = (ch.area) / (remaining.area) - 1 alpha = 1.11 fsm = 1 / (1 + alpha * lamda) res = outOfStock.area * 1000 + overlapArea * 1000 + dist_from_zero * 1 + 300 * fsm #+ dist_sum*5 return res
def ObjectiveFcn(particle, nVars, Stock, Order): f = 0 remaining = Stock newOrder = [ shapely.affinity.rotate(shapely.affinity.translate( Order[j], xoff=particle[j * 3], yoff=particle[j * 3 + 1]), particle[j * 3 + 2], origin='centroid') for j in range(len(Order)) ] # This fitness component is used to prevent cutting of polygons outside the boundaries of each stock union = shapely.ops.cascaded_union( newOrder) # the union of shapes with new positions and rotations f_OUT = union.difference(Stock) # the difference of union with stock f_OUT = f_OUT.area # the goal is to avoid overlapping the polygons cut # calculate the area of the shapes overlapped by many shapes areaSum = sum([newOrder[w].area for w in range(0, len(newOrder))]) #the sum of the areas of the shapes of each order # Overlap area is the difference of the sum of the areas of the shapes of each order form # the UNION area of the individual shapes of the order with the placements of the proposed solution f_OVERLAP = areaSum - union.area # if there is no overlap, the difference must be zero, and #if such a difference expresses the overlapping portion # Attraction of shapes to each other # The aim is to reduce the distances between the shapes in descending order by area sortedOrder = np.argsort( np.array([newOrder[i].area for i in range(0, len(newOrder))])) sortedM = [newOrder[w] for w in sortedOrder] #This distance is the shortest and the final is the sum of all this distances f_DIST = sum([ sortedM[i].distance(sortedM[i + 1]) for i in range(0, len(sortedM) - 1) ]) # Attraction of shapes to the x and y axis(0,0) using areas # Calculte the sum of the x's and the centroid of the shapes multiplied by the area of the figure f_ATTR_x = sum([ newOrder[i].area * (newOrder[i].centroid.x) for i in range(0, len(newOrder)) ]) # Calculte the sum of the y's and the centroid of the shapes multiplied by the area of the figure f_ATTR_y = sum([ newOrder[i].area * (newOrder[i].centroid.y) for i in range(0, len(newOrder)) ]) # term will be its summarise f_ATTR = f_ATTR_x + f_ATTR_y # This fitness component quantifies the smoothness of the object by evaluating the shape of its external borders. # Objects with strongly irregular shape are penalized, # to avoid the simultaneous extraction of spatially distant regions of the same label. Initially, we compute the following ratio remaining = Stock.difference(union) hull = remaining.convex_hull l = hull.area / remaining.area - 1 # Objects with small λare nearly convex (𝜆=0for ideally convex) which is considered as the ideal shape of an object. # Parameter αcontrols the slope of the function. a = 1.11 # To obtain normalized fitness values in the range [0,1], the smoothness fitness is defined as follows f_SMO = 1 / (1 + a * l) # The overall fitness function is obtained by combining the above criteria f = (f_OUT * w_f_OUT) + (f_OVERLAP * w_f_OVERLAP) + (f_DIST * w_f_DIST) + ( f_ATTR * w_f_ATTR) + (f_SMO * w_f_SMO) # print(f) return f
#np.random.seed(1) #Start calculating time in order to calculate converge time start_time = time.time() orders = [Order1, Order2, Order3] #Store all orders into a list shapesTotal = sum([len(Order1), len(Order2), len(Order3)]) #get number of polygons resList = [] resListPerStock = [] nonFitted = [] iterationsList = [] orderN = len(orders) # Copy Stock into remainning varaible remaining = Stock.copy() remainingN = len(remaining) count = 0 shapesF = 0 #runs as long as the order list is not empty while (orders): # a flag indicating whether the order has been fulfilled flag = False count = count + 1 tolerance = 1e-4 # place the 1st order as current and starting calculations currentOrder = orders[0] #Calculate the sum of the areas of the order shapes