def _tile_search1(Jobs, TSoFar, firstAddPoint, cfg=config.Config): """This recursive function does the following with an existing tiling TSoFar: * For each 4-tuple (Xdim,Ydim,job,rjob) in Jobs, the non-rotated 'job' is selected * For the non-rotated job, the list of valid add-points is found * For each valid add-point, the job is placed at this point in a new, cloned tiling. * The function then calls its recursively with the remaining list of jobs. * The rotated job is then selected and the list of valid add-points is found. Again, for each valid add-point the job is placed there in a new, cloned tiling. * Once again, the function calls itself recursively with the remaining list of jobs. * The best tiling encountered from all recursive calls is returned. If TSoFar is None it means this combination of jobs is not tileable. The side-effect of this function is to set _TBestTiling and _TBestScore to the best tiling encountered so far. _TBestTiling could be None if no valid tilings have been found so far. """ global _StartTime, _CkpointTime, _Placements, _TBestTiling, _TBestScore, _Permutations, _PrintStats if not TSoFar: return (None, float(sys.maxint)) if not Jobs: # Update the best tiling and score. If the new tiling matches # the best score so far, compare on number of corners, trying to # minimize them. score = TSoFar.area() if score < _TBestScore: _TBestTiling,_TBestScore = TSoFar,score elif score == _TBestScore: if TSoFar.corners() < _TBestTiling.corners(): _TBestTiling,_TBestScore = TSoFar,score _Placements += 1 if firstAddPoint: _Permutations += 1 return xspacing = cfg['xspacing'] yspacing = cfg['yspacing'] minInletSize = tiling.minDimension(Jobs) TSoFar.removeInlets(minInletSize) for job_ix in range(len(Jobs)): # Pop off the next job and construct remaining_jobs, a sub-list # of Jobs with the job we've just popped off excluded. Xdim,Ydim,job,rjob = Jobs[job_ix] remaining_jobs = Jobs[:job_ix]+Jobs[job_ix+1:] if 0: print "Level %d (%s)" % (level, job.name) TSoFar.joblist() for J in remaining_jobs: print J[2].name, ", ", print print '-'*75 # Construct add-points for the non-rotated and rotated job. # As an optimization, do not construct add-points for the rotated # job if the job is a square (duh). addpoints1 = TSoFar.validAddPoints(Xdim+xspacing,Ydim+yspacing) # unrotated job if Xdim != Ydim: addpoints2 = TSoFar.validAddPoints(Ydim+xspacing,Xdim+yspacing) # rotated job else: addpoints2 = [] # Recursively construct tilings for the non-rotated job and # update the best-tiling-so-far as we do so. if addpoints1: for ix in addpoints1: # Clone the tiling we're starting with and add the job at this # add-point. T = TSoFar.clone() T.addJob(ix, Xdim+xspacing, Ydim+yspacing, job) # Recursive call with the remaining jobs and this new tiling. The # point behind the last parameter is simply so that _Permutations is # only updated once for each permutation, not once per add-point. # A permutation is some ordering of jobs (N! choices) and some # ordering of non-rotated and rotated within that ordering (2**N # possibilities per ordering). _tile_search1(remaining_jobs, T, firstAddPoint and ix==addpoints1[0]) elif firstAddPoint: # Premature prune due to not being able to put this job anywhere. We # have pruned off 2^M permutations where M is the length of the remaining # jobs. _Permutations += 2L**len(remaining_jobs) if addpoints2: for ix in addpoints2: # Clone the tiling we're starting with and add the job at this # add-point. Remember that the job is rotated so swap X and Y # dimensions. T = TSoFar.clone() T.addJob(ix, Ydim+xspacing, Xdim+yspacing, rjob) # Recursive call with the remaining jobs and this new tiling. _tile_search1(remaining_jobs, T, firstAddPoint and ix==addpoints2[0]) elif firstAddPoint: # Premature prune due to not being able to put this job anywhere. We # have pruned off 2^M permutations where M is the length of the remaining # jobs. _Permutations += 2L**len(remaining_jobs) # If we've been at this for 3 seconds, print some status information if _PrintStats and time.time() > _CkpointTime: printTilingStats() # Check for timeout - changed to file config if (config.Config['searchtimeout'] > 0) and ((time.time() - _StartTime) > config.Config['searchtimeout']): raise KeyboardInterrupt gerbmerge.updateGUI("Performing automatic layout...")
def _tile_search2(Jobs, X, Y, cfg=config.Config): global _CkpointTime, _Placements, _TBestTiling, _TBestScore r = random.Random() N = len(Jobs) # M is the number of jobs that will be placed randomly. # N-M is the number of jobs that will be searched exhaustively. M = N - config.RandomSearchExhaustiveJobs M = max(M, 0) xspacing = cfg['xspacing'] yspacing = cfg['yspacing'] # Must escape with Ctrl-C while 1: T = tiling.Tiling(X, Y) joborder = r.sample(range(N), N) minInletSize = tiling.minDimension(Jobs) for ix in joborder[:M]: Xdim, Ydim, job, rjob = Jobs[ix] T.removeInlets(minInletSize) if r.choice([0, 1]): addpoints = T.validAddPoints(Xdim + xspacing, Ydim + yspacing) if not addpoints: break pt = r.choice(addpoints) T.addJob(pt, Xdim + xspacing, Ydim + yspacing, job) else: addpoints = T.validAddPoints(Ydim + xspacing, Xdim + yspacing) if not addpoints: break pt = r.choice(addpoints) T.addJob(pt, Ydim + xspacing, Xdim + yspacing, rjob) else: # Do exhaustive search on remaining jobs if N - M: remainingJobs = [] for ix in joborder[M:]: remainingJobs.append(Jobs[ix]) tilesearch1.initialize(0) tilesearch1._tile_search1(remainingJobs, T, 1) T = tilesearch1.bestTiling() if T: score = T.area() if score < _TBestScore: _TBestTiling, _TBestScore = T, score elif score == _TBestScore: if T.corners() < _TBestTiling.corners(): _TBestTiling, _TBestScore = T, score _Placements += 1 # If we've been at this for 3 seconds, print some status information if time.time() > _CkpointTime: printTilingStats() # Check for timeout - changed to file config if (config.Config['searchtimeout'] > 0) and ( (time.time() - _StartTime) > config.Config['searchtimeout']): raise KeyboardInterrupt gerbmerge.updateGUI("Performing automatic layout...")
def _tile_search2(Jobs, X, Y, cfg=config.Config): global _CkpointTime, _Placements, _TBestTiling, _TBestScore r = random.Random() N = len(Jobs) # M is the number of jobs that will be placed randomly. # N-M is the number of jobs that will be searched exhaustively. M = N - config.RandomSearchExhaustiveJobs M = max(M,0) xspacing = cfg['xspacing'] yspacing = cfg['yspacing'] # Must escape with Ctrl-C while 1: T = tiling.Tiling(X,Y) joborder = r.sample(range(N), N) minInletSize = tiling.minDimension(Jobs) for ix in joborder[:M]: Xdim,Ydim,job,rjob = Jobs[ix] T.removeInlets(minInletSize) if r.choice([0,1]): addpoints = T.validAddPoints(Xdim+xspacing,Ydim+yspacing) if not addpoints: break pt = r.choice(addpoints) T.addJob(pt, Xdim+xspacing, Ydim+yspacing, job) else: addpoints = T.validAddPoints(Ydim+xspacing,Xdim+yspacing) if not addpoints: break pt = r.choice(addpoints) T.addJob(pt, Ydim+xspacing, Xdim+yspacing, rjob) else: # Do exhaustive search on remaining jobs if N-M: remainingJobs = [] for ix in joborder[M:]: remainingJobs.append(Jobs[ix]) tilesearch1.initialize(0) tilesearch1._tile_search1(remainingJobs, T, 1) T = tilesearch1.bestTiling() if T: score = T.area() if score < _TBestScore: _TBestTiling,_TBestScore = T,score elif score == _TBestScore: if T.corners() < _TBestTiling.corners(): _TBestTiling,_TBestScore = T,score _Placements += 1 # If we've been at this for 3 seconds, print some status information if time.time() > _CkpointTime: printTilingStats() # Check for timeout - changed to file config if (config.Config['searchtimeout'] > 0) and ((time.time() - _StartTime) > config.Config['searchtimeout']): raise KeyboardInterrupt gerbmerge.updateGUI("Performing automatic layout...")
def _tile_search1(Jobs, TSoFar, firstAddPoint, cfg=config.Config): """This recursive function does the following with an existing tiling TSoFar: * For each 4-tuple (Xdim,Ydim,job,rjob) in Jobs, the non-rotated 'job' is selected * For the non-rotated job, the list of valid add-points is found * For each valid add-point, the job is placed at this point in a new, cloned tiling. * The function then calls its recursively with the remaining list of jobs. * The rotated job is then selected and the list of valid add-points is found. Again, for each valid add-point the job is placed there in a new, cloned tiling. * Once again, the function calls itself recursively with the remaining list of jobs. * The best tiling encountered from all recursive calls is returned. If TSoFar is None it means this combination of jobs is not tileable. The side-effect of this function is to set _TBestTiling and _TBestScore to the best tiling encountered so far. _TBestTiling could be None if no valid tilings have been found so far. """ global _StartTime, _CkpointTime, _Placements, _TBestTiling, _TBestScore, _Permutations, _PrintStats if not TSoFar: return (None, float(sys.maxint)) if not Jobs: # Update the best tiling and score. If the new tiling matches # the best score so far, compare on number of corners, trying to # minimize them. score = TSoFar.area() if score < _TBestScore: _TBestTiling,_TBestScore = TSoFar,score elif score == _TBestScore: if TSoFar.corners() < _TBestTiling.corners(): _TBestTiling,_TBestScore = TSoFar,score _Placements += 1 if firstAddPoint: _Permutations += 1 return xspacing = cfg['xspacing'] yspacing = cfg['yspacing'] minInletSize = tiling.minDimension(Jobs) TSoFar.removeInlets(minInletSize) for job_ix in range(len(Jobs)): # Pop off the next job and construct remaining_jobs, a sub-list # of Jobs with the job we've just popped off excluded. Xdim,Ydim,job,rjob = Jobs[job_ix] remaining_jobs = Jobs[:job_ix]+Jobs[job_ix+1:] if 0: print "Level %d (%s)" % (level, job.name) TSoFar.joblist() for J in remaining_jobs: print J[2].name, ", ", print print '-'*75 # Construct add-points for the non-rotated and rotated job. # As an optimization, do not construct add-points for the rotated # job if the job is a square (duh). addpoints1 = TSoFar.validAddPoints(Xdim+xspacing,Ydim+yspacing) # unrotated job if Xdim != Ydim: addpoints2 = TSoFar.validAddPoints(Ydim+xspacing,Xdim+yspacing) # rotated job else: addpoints2 = [] # Recursively construct tilings for the non-rotated job and # update the best-tiling-so-far as we do so. if addpoints1: for ix in addpoints1: # Clone the tiling we're starting with and add the job at this # add-point. T = TSoFar.clone() T.addJob(ix, Xdim+xspacing, Ydim+yspacing, job) # Recursive call with the remaining jobs and this new tiling. The # point behind the last parameter is simply so that _Permutations is # only updated once for each permutation, not once per add-point. # A permutation is some ordering of jobs (N! choices) and some # ordering of non-rotated and rotated within that ordering (2**N # possibilities per ordering). _tile_search1(remaining_jobs, T, firstAddPoint and ix==addpoints1[0]) elif firstAddPoint: # Premature prune due to not being able to put this job anywhere. We # have pruned off 2^M permutations where M is the length of the remaining # jobs. _Permutations += 2L**len(remaining_jobs) if addpoints2: for ix in addpoints2: # Clone the tiling we're starting with and add the job at this # add-point. Remember that the job is rotated so swap X and Y # dimensions. T = TSoFar.clone() T.addJob(ix, Ydim+xspacing, Xdim+yspacing, rjob) # Recursive call with the remaining jobs and this new tiling. _tile_search1(remaining_jobs, T, firstAddPoint and ix==addpoints2[0]) elif firstAddPoint: # Premature prune due to not being able to put this job anywhere. We # have pruned off 2^M permutations where M is the length of the remaining # jobs. _Permutations += 2L**len(remaining_jobs) # If we've been at this for 3 seconds, print some status information if _PrintStats and time.time() > _CkpointTime: printTilingStats() # Check for timeout if (config.SearchTimeout > 0) and (time.time() - _StartTime > config.SearchTimeout): raise KeyboardInterrupt gerbmerge.updateGUI("Performing automatic layout...")