def calculateFitnessSolution(solution, constraints=None): levelSkeleton = solution.levelSkeleton wallEvaluator = WallEvaluator(levelSkeleton) if constraints is not None: rad_w, ecc_w, area_w, length_w = constraints['rad_w'], constraints['ecc_w'],\ constraints['area_w'], constraints['length_w'] else: rad_w, ecc_w, area_w, length_w = 0.5, -0.5, 1, 1 size = 0 dis = 0 totalX = 0 totalY = 0 lengthX = 0 lengthY = 0 needed = levelSkeleton.getVoileLengthNeeded(constraints['ratio']) centerV = levelSkeleton.slabSkeleton.poly.centroid() centerV = Pnt(centerV.x, centerV.y) vecUni = Pnt(0, 0) for wallSkeleton in levelSkeleton.wallSkeletons: # print "attached voiles : " + str(len(wallSkeleton.attachedVoiles)) evalData = wallEvaluator.calculateFitnessWall(wallSkeleton) d, s, lx, ly = evalData.dis, evalData.size, evalData.totalLengthX, evalData.totalLengthY dis += d size += s totalX += lx totalY += ly lengthX += evalData.lengthX lengthY += evalData.lengthY vecUni += evalData.vecUni cntr = levelSkeleton.getCenterFromShear() Rx, Ry = levelSkeleton.getTorsionalRadius(centerV) momentx, momenty = levelSkeleton.slabSkeleton.poly.momentX( ), levelSkeleton.slabSkeleton.poly.momentY() if momentx < 0 or momenty < 0: print((momentx, momenty)) eval(input()) radiuses = (Rx + Ry) / ( abs(Rx - Ry) + 0.000001 ) #abs(1-(Ry/(momentx+momenty))) + abs(1-(Rx/(momentx+momenty))) area = solution.getAreaCoveredBoxes(constraints['d']) coeffs = { 'rad': rad_w, 'sym': ecc_w, 'lengthShearX': length_w / 2., 'lengthShearY': length_w / 2., # 'overlapped': -1, # 'unif': 0, 'area': area_w } def getScoreLength(lengthA, total): if lengthA < needed: scoreLengthA = math.pow(lengthA / needed, 3) else: scoreLengthA = 1 - (lengthA - needed) / needed return scoreLengthA scoreLengthX = getScoreLength(lengthX, totalX) scoreLengthY = getScoreLength(lengthY, totalY) areaNorm = sum( voileSkeleton.getSurrondingBox(constraints['d']).area for wallSkeleton in levelSkeleton.wallSkeletons for voileSkeleton in wallSkeleton.getAllVoiles()) if areaNorm == 0: areaNorm = -1 ar = -1 else: ar = math.sqrt(areaNorm) fitV = { 'radX': Rx, 'radY': Ry, 'rad': radiuses, 'sym': max([0, distance(cntr, centerV) / ar]), 'lengthShearX': scoreLengthX, 'lengthShearY': scoreLengthY, 'unif': vecUni.magn(), 'area': area / levelSkeleton.getSlabArea(), 'overlapped': max([0, solution.getOverlappedArea(constraints['d']) / areaNorm]), 'lengthX': lengthX, 'lengthY': lengthY } fitness = 0 for key in coeffs: fitness += fitV[key] * coeffs[key] fitV['totalScore'] = fitness # fitness = fitV['area'] return fitV
class BoxSkeleton(PolySkeleton): def __init__(self, poly, pnts=None): super(BoxSkeleton, self).__init__(poly) if pnts: self.topLeftPnt, self.vecLength, self.vecWidth = pnts return self.topLeftPnt = Pnt self.vecLength = Pnt self.vecWidth = Pnt # if len(poly.points) != 4: # raise NotBoxError("not four points") # else: # pnts = poly.points # for p in pnts: # print p # vec1 = pnts[0] - pnts[1] # vec2 = pnts[3] - pnts[2] # threshold = vec1.magn()*0.1 # print ("vec1: "+str(vec1)+" vec2: "+str(vec2)) # if not (abs(vec1.x() - vec2.x()) <= threshold and abs(vec1.y()-vec2.y()) <= threshold): # raise NotBoxError("not parallel") self._getTopLeftPoint() def _getTopLeftPoint(self): pnts = self.poly.points size = len(pnts) maxVec = None topPnt = None endPnt = None for index, pnt in enumerate(pnts): vec = pnts[(index + 1) % size] - pnt if not maxVec or maxVec.magn() < vec.magn(): maxVec = vec topPnt = pnt maxVec2 = None for index, pnt in enumerate(pnts): if pnt != topPnt: ePnt = pnts[(index + 1) % size] vec = ePnt - pnt if not maxVec2 or maxVec2.magn() < vec.magn(): maxVec2 = vec endPnt = ePnt # if maxVec.magn() - maxVec2.magn() > 0.1: # print "mVec: " + str(maxVec.magn()) + " mVec2: " + str(maxVec2.magn()) self.vecLength = maxVec self.vecWidth = endPnt - topPnt if self.vecWidth.magn() == 0: self.vecWidth = Pnt(0.00000001, 0.00000001) # print ("end", endPnt, "start", topPnt, "1", endPnt.x(), endPnt.y(), topPnt.x(), topPnt.y()) # for pnt in pnts: # print (pnt, pnt.x(), pnt.y()) # # print "ennnnnddddd" self.topLeftPnt = topPnt def _getTopLeftPoint4(self): pnts = self.poly.points minXpnt = min(pnts, key=lambda p: p.x()) self.topLeftPnt = minXpnt index = 0 for pnt in pnts: if minXpnt == pnt: break index += 1 i1 = (index + 1) % 4 i2 = (index - 1) % 4 vec1 = pnts[i1] - minXpnt vec2 = pnts[i2] - minXpnt if vec1.magn() > vec2.magn(): self.vecWidth = vec2 self.vecLength = vec1 else: self.vecWidth = vec1 self.vecLength = vec2 def getWidth(self): return self.vecWidth.magn() def getHeight(self): return self.vecLength.magn()
def calculateFitnessSolution(solution, constraints=None, comb=[0, 0, 0, 0]): # ReserveWallS = [] # for wallskeleton in solution.levelSkeleton.wallSkeletons: # if wallskeleton.iscolumnParent: # ReserveWallS.append(wallskeleton) # for wallskeleton in ReserveWallS: solution.levelSkeleton.wallSkeletons.remove(wallskeleton) levelSkeleton = solution.levelSkeleton wallEvaluator = WallEvaluator(levelSkeleton) if constraints is not None: rad_w, ecc_w, area_w, length_w = constraints['rad_w'], constraints['ecc_w'],\ constraints['area_w'], constraints['length_w'] else: rad_w, ecc_w, area_w, length_w = 0, -0.5, 1, 1 size = 0 dis = 0 totalX = 0 totalY = 0 lengthX = 0 lengthY = 0 needed = levelSkeleton.getVoileLengthNeeded(constraints['ratio']) centerV = levelSkeleton.slabSkeleton.poly.centroid() centerV = Pnt(centerV.x, centerV.y) vecUni = Pnt(0, 0) for wallSkeleton in levelSkeleton.wallSkeletons: # print "attached voiles : " + str(len(wallSkeleton.attachedVoiles)) evalData = wallEvaluator.calculateFitnessWall(wallSkeleton) d, s, lx, ly = evalData.dis, evalData.size, evalData.totalLengthX, evalData.totalLengthY dis += d size += s totalX += lx totalY += ly if not wallSkeleton.iscolumnParent: lengthX += evalData.lengthX lengthY += evalData.lengthY vecUni += evalData.vecUni # print("columns direction length", toAddYneeded, toAddXneeded) # print("total here", lengthY, lengthX) cntr = levelSkeleton.getCenterFromShear() Rx, Ry = levelSkeleton.getTorsionalRadius(centerV) momentx, momenty = levelSkeleton.slabSkeleton.poly.momentX( ), levelSkeleton.slabSkeleton.poly.momentY() if momentx < 0 or momenty < 0: print((momentx, momenty)) eval(input()) # radiuses = (Rx + Ry)/(abs(Rx-Ry)+0.000001) #abs(1-(Ry/(momentx+momenty))) + abs(1-(Rx/(momentx+momenty))) rx = math.sqrt(momentx / levelSkeleton.slabSkeleton.poly.area()) # Torsional radius ry = math.sqrt(momenty / levelSkeleton.slabSkeleton.poly.area()) radiuses = (Rx / rx + Ry / ry) * 0.5 scoreDist = levelSkeleton.ScoreOfUnacceptableVoiles()[0] # scoreDist = 0 a = solution.getOverlappedArea(constraints['d']) effectiveArea = solution.getEffectiveArea() overlappedArea = solution.geteffectiveOverlappedArea(effectiveArea) ex = abs(cntr.x() - centerV.x()) ey = abs(cntr.y() - centerV.y()) coeffs = { 'rad': comb[2], 'sym': comb[0], 'lengthShearX': 0, 'lengthShearY': 0, 'overlapped': 0, # 'unif': 0, 'area': comb[1], 'distance': 0, 'distribution': comb[3], } # print('this combination is', comb) def getScoreLength(lengthA, total): if lengthA > needed: scoreLengthA = math.pow(needed / lengthA, 3) else: scoreLengthA = 1 - (needed - lengthA) / needed return scoreLengthA def getScoreArea(area, slabArea): if area: if area > 0.2 * slabArea: scoreArea = math.pow(0.02 * slabArea / area, 3) else: scoreArea = 1 - (0.2 * slabArea - area) / (0.2 * slabArea) return scoreArea else: return 0 def getScoreOverlapped(overlapped, totalArea): if totalArea >= overlapped: return 1 - overlapped / totalArea else: return 0 def getScoreSymEcc(ex, ey, Rx, Ry): if Ry == 0: Ry = 0.1 if Rx == 0: Rx = 0.1 return 0.5 * (2 - ex / (0.3 * Rx) - ey / (0.3 * Ry)) def getDistrubtionScore(lx, ly, LX, LY): if ly and lx: if ly > lx: s1 = abs(lx / ly) else: s1 = abs(ly / lx) else: s1 = -1 return s1 LX = levelSkeleton.slabSkeleton.poly.MaxCoords().x( ) - levelSkeleton.slabSkeleton.poly.MinCoords().x() LY = levelSkeleton.slabSkeleton.poly.MaxCoords().y( ) - levelSkeleton.slabSkeleton.poly.MinCoords().y() scoreLengthX = getScoreLength(lengthX, totalX) scoreLengthY = getScoreLength(lengthY, totalY) scoreArea = getScoreArea(effectiveArea, levelSkeleton.slabSkeleton.poly.area()) scoreOverlapped = getScoreOverlapped(overlappedArea, effectiveArea) SymScore = getScoreSymEcc(ex, ey, Rx, Ry) distributionScore = getDistrubtionScore(lengthX, lengthY, LX, LY) # print("\nscore length", scoreLengthX, scoreLengthY) # print("effective inslab area:", effectiveArea," score:", scoreArea) # print("overlapped area", overlappedArea," score:",scoreOverlapped) # print("eccentricty", SymScore) # print("Distance score", scoreDist) # print("radius score", radiuses) # print('distributionScore', distributionScore) areaNorm = sum( voileSkeleton.getSurrondingBox(constraints['d']).area for wallSkeleton in levelSkeleton.wallSkeletons for voileSkeleton in wallSkeleton.getAllVoiles()) if areaNorm == 0: areaNorm = -1 ar = -1 else: ar = math.sqrt(areaNorm) fitV = { 'radX': Rx, 'radY': Ry, 'rad': radiuses, 'sym': SymScore, #max([0,distance(cntr,centerV)/ar]), 'lengthShearX': scoreLengthX, 'lengthShearY': scoreLengthY, 'unif': vecUni.magn(), 'area': scoreArea, #area/levelSkeleton.getSlabArea(), 'overlapped': scoreOverlapped, 'lengthX': lengthX, 'lengthY': lengthY, 'distance': scoreDist, 'distribution': distributionScore } fitness = 0 for key in coeffs: # print("fitness of",key,':',fitV[key]*coeffs[key] ) fitness += fitV[key] * coeffs[key] fitV['totalScore'] = fitness return fitV