def minDeletions2(self, s): """ :type s: str :rtype: int """ cnt = Counter(s) s = SortedSet([_ for _ in range(1, max(cnt.values()) + 1)], key=lambda x: -x) s -= SortedSet(list(cnt.values())) res = 0 cnts = Counter(cnt.values()) for i in sorted(cnts.keys(), reverse=True): if cnts[i] > 1: k = cnts[i] while s and s[0] >= i: s.pop(0) while s and k > 1: res += i - s[0] s.pop(0) k -= 1 if k > 1: while k > 1: res += i k -= 1 return res
def findTheWinner(self, n: int, k: int) -> int: ct = SortedSet([i for i in range(1,n+1)]) a = 0 while len(ct) > 1: a = (a + k -1) % len(ct) ct.pop(a) return ct[0]
def minDeletions(self, s): """ :type s: str :rtype: int """ cnt = Counter(s) s = SortedSet([_ for _ in range(1, max(cnt.values()) + 1)], key=lambda x: -x) s -= SortedSet(list(cnt.values())) res = 0 cnts = sorted(cnt.values(), reverse=True) f = -1 # print(cnts,s ) for i in range(len(cnts)): while s and s[0] >= cnts[i]: s.pop(0) if cnts[i] == f: if s: res += (cnts[i] - s[0]) s.pop(0) else: res += cnts[i] f = cnts[i] return res
def rates_rabbit_callback(ch, method, properties, body): id, rate = body.decode('utf-8').split(',') print("rabbit: id: {}, rate: {}".format(id, rate)) redis_db_rates.hincrby(id, "rates_amount", 1) redis_db_rates.hincrby(id, "rates_sum", rate) # Calculate ranking n_max = 0 rates_sum_all = 0 rates_amount_all = 0 for key in redis_db_rates.keys(): try: product_rates_amount = int( redis_db_rates.hget(key, "rates_amount")) product_rates_sum = int(redis_db_rates.hget(key, "rates_sum")) rates_amount_all += product_rates_amount rates_sum_all += product_rates_sum n_max = max(n_max, product_rates_amount) except redis.exceptions.ResponseError: pass if rates_amount_all == 0: return r_0 = rates_sum_all / rates_amount_all highest_ranking_products = SortedSet() for key in redis_db_rates.keys(): try: product_rates_amount = int( redis_db_rates.hget(key, "rates_amount")) w = product_rates_amount / n_max product_ranking_rate = w * rate_of_product(key) + (1 - w) * r_0 highest_ranking_products.add((product_ranking_rate, key)) if len(highest_ranking_products) > N_OF_HIGHEST_RATED: highest_ranking_products.pop(0) except redis.exceptions.ResponseError: pass redis_db_rates.delete("highest_products") for _, id in highest_ranking_products: redis_db_rates.lpush("highest_products", int(id))
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool: set1 = SortedSet() i = 0 - k j = 0 while j < len(nums): if set1 and abs(nums[j] - set1[0]) <= t: return True else: if i >= 0 and set1: set1.pop(0) set1.add(nums[j]) i += 1 j += 1 return False
class PriorityQueue: """min first""" def __init__(self): self._priorities_with_counter = dict() self._tree = SortedSet() self._counter = 0 def add_or_update(self, value, priority): if value in self._priorities_with_counter: self._tree.remove((self._priorities_with_counter[value], value)) del self._priorities_with_counter[value] self._priorities_with_counter[value] = (priority, self._counter) self._tree.add(((priority, self._counter), value)) self._counter += 1 def get_priority(self, value): return self._priorities_with_counter[value][0] def remove_if_present(self, value): if value in self._priorities_with_counter: self._tree.remove((self._priorities_with_counter[value], value)) del self._priorities_with_counter[value] def __len__(self): return len(self._priorities_with_counter) def pop_first(self): """:returns (value, priority) of element with the lowest priority""" assert len(self) > 0, "priority queue is empty!" tmp, value = self._tree.pop(0) priority, _ = tmp del self._priorities_with_counter[value] return value, priority
def avoidFlood(self, rains: List[int]) -> List[int]: n = len(rains) d = {} res = [-1] * n ss = SortedSet() for i, r in enumerate(rains): if r == 0: ss.add(i) continue if r not in d: d[r] = i else: j = d[r] ind = ss.bisect_left(j) if ind == len(ss): return [] res[ss[ind]] = r ss.remove(ss[ind]) d[r] = i while ss: res[ss.pop()] = 1 return res
def run(self,in_data): n,m=in_data.no_tasks,in_data.no_machines l=in_data.tasks r=[] N=[] A=SortedSet(a(n),key=lambda idx:-l[idx].due_date) Y=[0 for _ in a(m)] for _ in a(n): while d(A)>0 and Y[2]>=l[A[-1]].due_date: S=A.pop() L=l[S] J(N,(-L.weight/R(L.duration),S)) if d(N)==0: O=g(s(lambda task_id:(self.v(Y,l[task_id]),task_id),A)) H=O[1] A.remove(H) else: _,H=q(N) L=l[H] r.append(H) p=0 for n in a(m): Y[n]=I(Y[n],p)+L.duration[n] p=Y[n] r=[e+1 for e in r] U=Schedule(in_data.no_tasks,r) y=Evaluator136775().score(in_data,U) return SS(score=y,schedule=U)
def allocate(self, spec): """ For each ASID pool in the spec, assign it to an unused ASID table slot. This modifies the spec's ASID pool objects in-place. Slot 0 is always skipped, because it is used for the init thread's ASID pool. We assume that the C loader also skips slot 0. This allocator allows ASID pools that already have assigned asid_high numbers. However, seL4 only allows allocating table slots in sequential order. Therefore, we raise AllocatorException if the spec's asid_high numbers cannot be obtained by the C loader. """ assert (isinstance(spec, Spec)) num_asid_high = get_object_size(ObjectType.seL4_ASID_Table) free_asid_highs = SortedSet(range(num_asid_high)) free_asid_highs.remove(0) # Init thread's asid_pools = [] # Get all ASIDPools for obj in spec.objs: if isinstance(obj, ASIDPool): asid_pools.append(obj) # Make deterministic asid_pools = sorted(asid_pools, key=lambda obj: obj.name) # Check availability of asid_highs; check existing claims for asid_pool in asid_pools: if asid_pool.asid_high is not None: if asid_pool.asid_high < 0 or asid_pool.asid_high >= num_asid_high: raise AllocatorException( "invalid asid_high of 0x%x, ASID pool %s" % (asid_pool.asid_high, asid_pool.name)) elif asid_pool.asid_high in free_asid_highs: raise AllocatorException( "asid_high 0x%x already in use, can't give to ASID pool %s" % (asid_pool.asid_high, asid_pool.name)) else: free_asid_highs.remove(asid_pool.asid_high) # Allocate free_asid_highs for asid_pool in asid_pools: if asid_pool.asid_high is None: if not free_asid_highs: raise AllocatorException( "ran out of asid_highs to allocate (next ASID pool: %s)" % asid_pool.name) else: asid_pool.asid_high = free_asid_highs.pop(0) # Check that asid_highs are contiguous for asid_pool in asid_pools: if asid_pool.asid_high > 0 and asid_pool.asid_high - 1 in free_asid_highs: raise AllocatorException( "asid_high not contiguous: %s wants 0x%x but 0x%x not assigned" % (asid_pool.name, asid_pool.asid_high, asid_pool.asid_high - 1))
def rebuild_MT(rZ, I, X, M, T): B = {} for i, v in X.items(): B[i + T - 1] = _cmp_MT_leaf(I, v, M) for i, v in rZ.items(): assert i not in B B[i] = v indexes = SortedSet(B.keys()) while len(indexes) >= 2: i2, i1 = indexes.pop(), indexes.pop() assert i1 + 1 == i2 and i2 % 2 == 0 i0 = i1 // 2 assert not i0 in indexes indexes.add(i0) B[i0] = _cmp_MT_node(I, B[i1], B[i2], M) assert len(indexes) == 1 and indexes.pop() == 0 return B
def collapse_nodes(graph, threshold=1000): surviving_nodes = SortedSet(graph.values(), lambda node: node.size) # This can be improved by using a custom heap like in LotterySampling min_node = surviving_nodes.pop(0) while min_node.size < threshold: print("Surviving nodes:", len(surviving_nodes), "-- Min size:", min_node.size) assert min_node.parent is None max_neighbour = None for node in min_node.neighbours: root_node = node.get_root() assert root_node in surviving_nodes if max_neighbour is None or max_neighbour.size < root_node.size: max_neighbour = root_node surviving_nodes.remove(max_neighbour) max_neighbour.merge_in(min_node) surviving_nodes.add(max_neighbour) min_node = surviving_nodes.pop(0)
def gen_clos_seq(start_n, progress=10): cache = dict() pend = SortedSet(range(1, start_n + 1)) while pend: n = pend.pop() collatz_stop(n, cache, pend) pend -= cache.keys() if len(cache) % progress == 0: logmsg('Cache size %d, misses %d', len(cache), len(pend)) seq = [(n, stop, miss) for (n, (stop, miss)) in cache.items()] return pd.DataFrame(seq, columns=COLS)
def act_on_battle(state, eval_function=eval_state): # initialize score dict # maximize state score primarily and minimize amount of actions secondarily scores = dict({(): (eval_function(state), 0)}) # initialize open and closed sets unvisited = SortedSet([()], key=scores.get) # while there are nodes unvisited while unvisited: # roll back to starting state state.undo_all() # get best unvisited node actions = unvisited.pop() # roll out actions to get into the intended state for action in actions: state.act(action) # discover all neighbors for action in state.available_actions: # do the respective action state.act(action) # calculate score and negative amount of actions scores[(*actions, action)] = eval_function(state), -(len(actions) + 1) # add this neighbor to the unvisited set unvisited.add((*actions, action)) # calculate time elapsed time_elapsed = time.perf_counter() - start_time # if we reached 175 ms, stop the search # 25 ms should be enough to finish if time_elapsed >= 0.175: # return the best actions so far best_actions = max(scores, key=scores.get) # if any direct attack is available, why not? for remaining_action in state.available_actions: if remaining_action.type == ActionType.ATTACK \ and remaining_action.target is None: best_actions = (*best_actions, remaining_action) return best_actions # roll back action state.undo() # return the actions needed to reach the best node we saw return max(scores, key=scores.get)
class SeatManager: def __init__(self, n: int): self.sm = SortedSet() for i in range(1, n + 1): self.sm.add(i) def reserve(self) -> int: res = self.sm.pop(0) return res def unreserve(self, seatNumber: int) -> None: self.sm.add(seatNumber)
def generate_first_k_a_b_sqrt2(k: int) -> List[float]: result = [] candidates = SortedSet([Number(0, 0)]) while len(result) < k: smallest = candidates.pop(0) result.append(smallest.val) candidates.add(Number(smallest.a + 1, smallest.b)) candidates.add(Number(smallest.a, smallest.b + 1)) return result
def generate_first_k_a_b_sqrt2(k): result = [] q = sqrt(2) tree = SortedSet([(0.0, 0, 0)]) while len(result) < k: smallest = tree.pop(0) result.append(smallest[0]) a = smallest[1] b = smallest[2] tree.add(((a + 1) + b * q, a + 1, b)) tree.add((a + (b + 1) * q, a, b + 1)) return result
class SortedSetKey: def __init__(self): self.dict = dict() self.sorted_set = SortedSet(key=self.get_key) def __getitem__(self, item): return self.sorted_set[item] def __len__(self): return len(self.sorted_set) def __str__(self): return str(self.sorted_set) def get_key(self, value): return self.dict[value] def get_reversed_list(self, index, count): return self[-1 - index:-1 - index - count:-1] def values(self): for value in self.sorted_set: yield value def clear(self): self.sorted_set.clear() self.dict.clear() def destroy(self): self.sorted_set = None def index(self, value): return self.sorted_set.index(value) def pop(self, index=-1): return self.sorted_set.pop(index) def add(self, value, rank): if value in self.sorted_set: self.sorted_set.remove(value) self.dict[value] = rank self.sorted_set.add(value) def remove(self, value): self.sorted_set.remove(value) del self.dict[value] def update(self, value_list, rank_list): self.sorted_set.difference_update(value_list) for i, value in enumerate(value_list): self.dict[value] = rank_list[i] self.sorted_set.update(value_list)
def concert_tickets(n, m, tickets, c_price): tickets.sort() cnt = Counter(tickets) t_values = SortedSet(cnt.keys()) t_values.add(-1) res = '' for c in c_price: i = t_values.bisect_right(c) - 1 if t_values[i] <= c: p = t_values[i] else: i = i - 1 p = t_values[i] if cnt[p] == 0: res += '-1\n' else: res += str(p) + '\n' cnt[p] -= 1 if cnt[p] == 0: cnt.pop(p) t_values.pop(i) return res
class Server: _ids = 0 def __init__(self): self.queue = SortedSet(key = lambda job: job.arrivalTime) self.numServers = 1 Server._ids +=1 self.busyServers = 0 self.serviceTimeDistribution = None self.name = "Server {}".format(Server._ids) self.In = None self.Out = None self.scheduler = None def receive(self, m): if m.event == "end": # end of service self.send(m.job) if len(self.queue) > 0: assert self.busyServers == self.numServers job = self.queue.pop(0) self.startService(job) else: assert self.busyServers > 0 self.busyServers -= 1 #self.departureStats() else: # receive new job assert "job" in m.event job = m.job job.setArrivalTime(self.scheduler.now()) serviceTime = self.serviceTimeDistribution.rvs() job.setServiceTime(serviceTime) job.log(self.scheduler.now(), "a", self.busyServers + len(self.queue)) if self.busyServers < self.numServers: self.busyServers += 1 self.startService(job) else: self.queue.add(job) def startService(self, job): job.log(self.scheduler.now(), "s", len(self.queue)) t = self.scheduler.now() + job.serviceTime m = Event(self, self, t, job = job, event = "end") self.scheduler.add(m) def send(self, job): # job departure job.log(self.scheduler.now(), "d", len(self.queue)) m = Event(self, self.Out, self.scheduler.now(), job = job, event = "job") self.scheduler.add(m) def setServiceTimeDistribution(self, distribution): self.serviceTimeDistribution = distribution
def pathfind(start, goal, collide_check_func): if collide_check_func(*goal) or collide_check_func(*start): return None q = SortedSet() def _heuristic(x1, y1, x2, y2): return (abs(x1 - x2) + abs(y1 - y2))**2 max_h = _heuristic(*start, *goal) q.add((max_h, start)) visited = set() curr_cost = dict() curr_cost[start] = (0, max_h) backtrace = dict() found = False while q: cost, point = q.pop(0) visited.add(point) if point == goal: found = True break for dir in ((0, 1), (0, -1), (1, 0), (-1, 0)): npoint = (point[0] + dir[0], point[1] + dir[1]) if collide_check_func(npoint[0], npoint[1]): continue if npoint in visited: continue h = _heuristic(*npoint, *goal) ncost = h + cost + 1 if npoint not in curr_cost or ncost < sum(curr_cost[npoint]): if npoint in curr_cost: q.remove((sum(curr_cost[npoint]), npoint)) q.add((ncost, npoint)) curr_cost[npoint] = (cost + 1, h) backtrace[npoint] = point if not found: return None l = [goal] while l[-1] != start: curr = backtrace[l[-1]] l.append(curr) l.reverse() return l
def find_path(graph, start, end): def dist(p1, p2): return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]) def heuristic(p): return dist(p, end) start = (start.x(), start.y()) end = (end.x(), end.y()) data = dict() q = SortedSet(key=lambda it: -sum(data[it])) # cost, heuristic data[start] = (0, heuristic(start)) q.add(start) back = dict() back[start] = start found = False while q: curr = q.pop() c, h = data[curr] prev = back[curr] dx = curr[0] - prev[0] dy = curr[1] - prev[1] if curr == end: found = True break for next in graph.get(curr, tuple()): if not (dx == 0 and next[0] - curr[0] == 0 or dy == 0 and next[1] - curr[1] == 0): np = 1e20 else: np = 0 if next in data: if c + dist(curr, next) + np < data[next][0]: q.discard(next) data[next] = (c + dist(curr, next) + np, heuristic(next)) back[next] = curr q.add(next) else: back[next] = curr data[next] = (c + dist(curr, next) + np, heuristic(next)) q.add(next) if found: path = [end] while path[-1] != start: path.append(back[path[-1]]) return list(reversed(path)) return list()
def astar(stare_initiala, stare_finala, euristica, lista_chei): nod_initial = Nod(stare_initiala, None, None) deschise = SortedSet([nod_initial]) scor_optim = SortedDict({tuple(stare_initiala): 0}) # [1, 1, 1, 1, 1] # (1, 1, 1, 1, 1) while len(deschise) > 0: # extragem nodul cu f minim nod = deschise[0] deschise.pop(0) # daca am ajuns la starea finala, ne oprim if nod.stare == stare_finala: return nod # generam succesorii si facem verificari lista_succesori = genereaza_succesori(nod, lista_chei, euristica) for succesor in lista_succesori: if scor_optim.__contains__(tuple(succesor.stare)) == False: # daca starea succesorului nu a mai fost intalnita pana acum, o inseram scor_optim[tuple(succesor.stare)] = succesor.g deschise.add(succesor) elif succesor.g < scor_optim[tuple(succesor.stare)]: # introducem/editam starea curenta in setul "deschis", dupa caz succesor_fals = Nod(succesor.stare, None, None) succesor_fals.f = scor_optim[tuple( succesor.stare)] + euristica(succesor.stare) if deschise.__contains__(succesor_fals) is True: deschise.discard(succesor) deschise.add(succesor) # daca starea curenta este intalnita cu un cost mai mic, o reactualizam scor_optim[tuple(succesor.stare)] = succesor.g return None
def djikstra(start, neighbors): dist = defaultdict(lambda: math.inf) pred = defaultdict(lambda: None) dist[start] = 0 queue = SortedSet(key=lambda v: dist[v]) queue.add(start) print("got here") while queue: u = queue.pop(0) for v, w_uv in neighbors(u): alt = dist[u] + w_uv if alt < dist[v]: if v in queue: queue.remove(v) dist[v] = alt pred[v] = u queue.add(v) return pred, dist
class FileSharing: def __init__(self, m: int): self.owned_by = {} self.user = {} self.max_id_assigned = 0 self.released = SortedSet() def get_user_id(self) -> int: if len(self.released): return self.released.pop(0) self.max_id_assigned += 1 return self.max_id_assigned def join(self, ownedChunks: List[int]) -> int: ret = self.get_user_id() for chunk in ownedChunks: if chunk not in self.owned_by: self.owned_by[chunk] = set() self.owned_by[chunk].add(ret) self.user[ret] = set(ownedChunks) return ret def leave(self, userID: int) -> None: for chunk in self.user[userID]: self.owned_by[chunk].remove(userID) self.user.pop(userID) self.released.add(userID) def request(self, userID: int, chunkID: int) -> List[int]: ret = sorted(self.owned_by.get(chunkID, [])) if ret: self.user[userID].add(chunkID) self.owned_by[chunkID].add(userID) return ret
def shortest_path_from(self, x, y, empty_square, infinity=100000): from sortedcontainers import SortedSet distance_map = self.map(const(infinity)) distance_map[y][x] = 0 pqueue = SortedSet() if empty_square(self[y - 1][x]): pqueue.add((1, y - 1, x)) distance_map[y - 1][x] = 1 if empty_square(self[y + 1][x]): pqueue.add((1, y + 1, x)) distance_map[y + 1][x] = 1 if empty_square(self[y][x - 1]): pqueue.add((1, y, x - 1)) distance_map[y][x - 1] = 1 if empty_square(self[y][x + 1]): pqueue.add((1, y, x + 1)) distance_map[y][x + 1] = 1 while len(pqueue) > 0: d, ty, tx = pqueue.pop(0) if d > distance_map[ty][tx]: continue if empty_square( self[ty - 1][tx]) and distance_map[ty - 1][tx] > d + 1: pqueue.add((d + 1, ty - 1, tx)) distance_map[ty - 1][tx] = d + 1 if empty_square( self[ty][tx - 1]) and distance_map[ty][tx - 1] > d + 1: pqueue.add((d + 1, ty, tx - 1)) distance_map[ty][tx - 1] = d + 1 if empty_square( self[ty][tx + 1]) and distance_map[ty][tx + 1] > d + 1: pqueue.add((d + 1, ty, tx + 1)) distance_map[ty][tx + 1] = d + 1 if empty_square( self[ty + 1][tx]) and distance_map[ty + 1][tx] > d + 1: pqueue.add((d + 1, ty + 1, tx)) distance_map[ty + 1][tx] = d + 1 return distance_map
class Timeline: def __init__(self, requests_file_name): self.timeline = SortedSet(key=lambda x: x.finish_time if type(x) is Response else x.created_time) with open(requests_file_name) as requests_input_file: for line in requests_input_file: tokens = line.split() time, app_name = int(tokens[0]), tokens[1] self.add(Request(app_name, time)) def get_next(self): return self.timeline.pop(0) if len(self.timeline) else None def add(self, obj): self.timeline.add(obj) def iterate(self): while True: next_elem = self.get_next() if next_elem: yield next_elem else: break
def walk_state_tree_a_star(state, end): visited = set([]) unvistied = set([state]) came_from = {} g_score = SortedSet([], key=lambda x: -x.distance_from_root) state.distance_from_root = 0 g_score.add(state) f_score = SortedSet([], key=lambda x: -x.distance_through_state) state.distance_through_state = state.distance(end) f_score.add(state) while unvistied: current = f_score.pop() if current == end: return get_path_length(came_from, current) unvistied.remove(current) visited.add(current) for s in current.generate_possible_states(): if s in visited: continue temp_score = current.distance_from_root + current.distance(s) if s not in unvistied: unvistied.add(s) elif temp_score > s.distance_from_root: continue came_from[s] = current s.distance_from_root = temp_score s.distance_through_state = s.distance_from_root + s.distance(end) f_score.add(s) g_score.add(s)
def a_star_search(start, goal, graph, heuristic_cost_estimate=heuristic_cost_estimate, get_neighbors=get_neighbors, get_edge_weight=get_edge_weight): gScore = {start: 0} # real cost to reach a node fScore = {start: heuristic_cost_estimate(start, goal, graph)} # estimated cost to reach a node closedSet = set() # set of processed nodes openSet = SortedSet(key=lambda node: fScore[node]) # set of nodes being processed openSet.add(start) cameFrom = {} # used to reconstruct the path at the end while openSet: current = openSet.pop(0) if current == goal: return construct_path(current, cameFrom) for neighbor in get_neighbors(current, graph) - closedSet: tentativeGScore = gScore[current] + get_edge_weight( current, neighbor, graph) if neighbor not in gScore or tentativeGScore < gScore[neighbor]: gScore[neighbor] = tentativeGScore fScore[neighbor] = tentativeGScore + heuristic_cost_estimate( neighbor, goal, graph) cameFrom[neighbor] = current if neighbor not in openSet: openSet.add(neighbor) closedSet.add(current) del fScore[current] del gScore[current] # clean up to free resources return []
def avoidFlood(self, rains): n = len(rains) ans = [-1 for i in range(n)] zeros = SortedSet([]) stack = {} impossible = False for i in range(n): if rains[i] == 0: zeros.add(i) continue if rains[i] in stack: idx = zeros.bisect(stack[rains[i]]) idxZero = None if idx < len(zeros) and zeros[idx] > stack[rains[i]]: idxZero = zeros.pop(idx) if idxZero is None: impossible = True break ans[idxZero] = rains[i] stack[rains[i]] = i if impossible: return [] stack = set() for i in range(n): if rains[i] > 0: stack.add(rains[i]) elif ans[i] == -1: if stack: ans[i] = stack.pop() else: ans[i] = random.randrange(1, n) else: stack.remove(ans[i]) # for i in zeros: # ans[i] = random.randrange(1, n) return ans
def py_star(width, height, costs, startIndex, endIndex, diagonalOk): if (width < 0 or height < 0): raise ValueError("Width and height have to be positive!") if (width * height != len(costs)): raise ValueError("Width * height != len(costs)!") if (startIndex < 0) or (startIndex > (len(costs) - 1)) or (endIndex < 0) or (endIndex > (len(costs) - 1)): raise ValueError( f"Start and end indices have to be in the range [0, {len(costs)})!" ) # find path from exit to start, this way when traversing the nodes from the start # every node points to the next one in the path startIndex, endIndex = endIndex, startIndex startPos = (startIndex % width, startIndex // width) endPos = endIndex % width, endIndex / width nodeMap = [ Node(idx, math.inf, 0.0, math.inf, None) for idx in range(0, len(costs)) ] endNode = nodeMap[endIndex] startNode = nodeMap[startIndex] startNode.sureCost = 0 startNode.heuristicCost = heuristicCost(startPos, endPos, diagonalOk) startNode.combinedCost = startNode.sureCost + startNode.heuristicCost DIAG_COST = math.sqrt(2) openlist = SortedSet([startNode], key=lambda node: node.combinedCost) closedlist = set() while len(openlist) > 0: current = openlist.pop(0) if current == endNode: # call with end and start switched to get correct direction back return (constructPath(endNode, startNode), closedlist) closedlist.add(current.idx) curX, curY = posFromIndex(current.idx, width) for dx in range(-1, 2): for dy in range(-1, 2): # skip diagonal entrys if diagonals are not viable if not diagonalOk and (abs(dx) == abs(dy)): continue x, y = curX + dx, curY + dy # skip if node would go outside rectangle # cannot wrap with unsigned cast like in cpp if (x - width + 1) * x > 0 or (y - height + 1) * y > 0: continue neighbor = nodeMap[current.idx + dx + dy * width] # skip previously visited nodes, including the current node if neighbor.idx in closedlist: continue # skip if node is not passable if costs[neighbor.idx] < 0: continue diagonalMove = (dx * dy) != 0 newSureCost = current.sureCost + (DIAG_COST if diagonalMove else 1) * costs[neighbor.idx] if newSureCost < neighbor.sureCost: # Make sure to not invalidate the ordered set openlist.discard(neighbor) neighbor.sureCost = newSureCost neighbor.heuristicCost = heuristicCost((x, y), endPos, diagonalOk) # combined cost for ordering of the open set neighbor.combinedCost = neighbor.sureCost + neighbor.heuristicCost neighbor.parent = current openlist.add(neighbor) return ([-1], closedlist)
def test_pop(): temp = SortedSet(range(0, 100), load=7) temp.pop() temp.pop(0) assert all(temp[val] == (val + 1) for val in range(98))
class RequestQ(object): ''' sorts queued pages via their rating @see protocol.Request keeps track of visited pages ''' def __init__(self, jitter=0.0, action_limit=16, param_key_limit=16, depth_limit=16): self.queue = SortedSet(key=lambda _: _.rating) self._visited = set() self._cull = {} self.write_lock = Semaphore() self.not_empty = Event() self.action_limit = action_limit self.param_key_limit = param_key_limit self.depth_limit = depth_limit self._visited_tree = Tree() self.jitter = jitter def visited(self, request): if(any([ _(request) for _ in [ self.cull_by_hash, self.cull_by_depth, self.cull_by_action, self.cull_by_param_keys ]])): return True return False def cull_by_depth(self, request): if len(request.action.split('/')) > self.depth_limit: return True return False def cull_by_hash(self, request): request_hash = request.__hash__() if request_hash in self._visited: return True self._visited.add(request_hash) return False def cull_by_action(self, request): endpoint_hash = request.endpoint.__hash__() self._cull.setdefault(endpoint_hash, CullNode()) count = self._cull[endpoint_hash].action_count + 1 self._cull[endpoint_hash].action_count = count if count > self.action_limit: logging.debug('culling {} with count {}'.format(request.url, count)) return True return False def cull_by_param_keys(self, request): if len(request.all_params()) == 0: return False endpoint_hash = request.endpoint.__hash__() self._cull.setdefault(endpoint_hash, CullNode()) for key in request.all_keys(): key_hash = key.__hash__() self._cull[endpoint_hash].setdefault(key_hash, 0) count = self._cull[endpoint_hash][key_hash] + 1 self._cull[endpoint_hash][key_hash] = count if count <= self.param_key_limit: return False else: logging.debug('culling candidate {} with {} {} keys'.format(request.url, count, key)) logging.debug('culling {}'.format(request.url)) return True def inv_param_key_frq(self, request): if len(request.all_params()) == 0 or (request.body is not None and request.all_params() == 1): return 0 endpoint_hash = request.endpoint.__hash__() param_key_rating = sum(map(lambda (k,v): v, filter(lambda (k,v): k in [_.__hash__() for _ in request.all_keys()], self._cull[endpoint_hash].iteritems()))) return 1 - param_key_rating/float(sum(self._cull[endpoint_hash].values()) or 1) def put(self, request): with self.write_lock: if not self.visited(request): request.rating += random.uniform(0, self.jitter) inv_path_frq = self._visited_tree.rate(request.endpoint) logging.debug('{} inverse path frequency rating for {}'.format(inv_path_frq, request)) request.rating += inv_path_frq inv_param_key_frq = self.inv_param_key_frq(request) logging.debug('{} inverse param key frequency rating for {}'.format(inv_param_key_frq, request)) request.rating += inv_param_key_frq self._visited_tree.visit(request.endpoint) self.queue.add(request) self.not_empty.set() def qsize(self): return len(self.queue) def get(self): self.not_empty.wait() with self.write_lock: try: return self.queue.pop() except IndexError: logging.error('queue tried to pop off of empty list') raise Done() finally: if self.qsize()==0: self.not_empty.clear()
graph[node] = SortedSet() graph[node].add(dep) if dep not in rgraph: rgraph[dep] = SortedSet() rgraph[dep].add(node) print('nodes', nodes, 'len', len(nodes)) print('graph', graph) print('rgraph', rgraph) available = SortedSet() done = set() find_first() print('avail', available) first_node = available.pop(0) print('next', first_node) steps = [first_node] process_step(first_node) while len(available) > 0: #print('rgraph', rgraph) print('avail', available) next_node = available.pop(0) print('next', next_node) steps.append(next_node) if next_node not in graph: break
class Server(Machine): _ids = 0 def __init__(self): state = ['Up', 'Failed', 'Maintenance', 'Blocked'] Machine.__init__(self, states = state, initial='Up') self.add_transition('start', 'Up', 'Up', after = "startJob") self.add_transition('fail', 'Up', 'Failed', after = 'startFail') self.add_transition('repair', 'Failed', 'Up', after = 'rep') self.add_transition('maint', 'Up', 'Maintenance', after='startmaint') self.add_transition('maintcpl', 'Maintenance', 'Up') self.add_transition('interrep', 'Failed', 'Maintenance', after='startmaint') self.add_transition('block', 'Up', 'Blocked') self.add_transition('unblock', 'Blocked', 'Up') self.queue = SortedSet(key = lambda job: job.arrivalTime) self.numServers = 1 self.busyServers = 0 self.prevState = None Server._ids +=1 self.serviceTimeDistribution = None self.name = "Server {}".format(Server._ids) self.In = None self.Out = None self.scheduler = None self.activejob = None self.interuptjob = None #debugging self.jobsarrived = 0 self.jobsprocessed = 0 self.numfailures = 0 self.nummaint = 0 self.onzin = 0 ##### Process logic ##### # starting and ending jobs # def startJob(self,job): # logging job.log(self.scheduler.now(), "s", len(self.queue)) self.activejob = job # schedule job end t = self.scheduler.now() + job.serviceTime m = Event(self, self, t, job = job, event = "end") self.scheduler.add(m) def end(self, m): self.send(m.job) self.jobsprocessed +=1 self.activejob = None if len(self.queue) > 0 and self.state == 'Up': job = self.queue.pop(0) self.start(job) else: self.busyServers -= 1 #self.departureStats() # starting and ending jobs # # Failures # def rep(self, temp): if self.interuptjob: self.resumejob() if not(self.scheduler.completed): self.generateFailure() def startFail(self, temp): if self.activejob: self.interuptJob() self.numfailures +=1 t = self.scheduler.now() + 1 m = Event(self, self, t, job = None, event = "repair") self.scheduler.add(m) def generateFailure(self): t = self.scheduler.now() + 200 m = Event(self, self, t, job = None, event = "fail") self.scheduler.add(m) # Failures # # Maintenance # def generateMaintenance(self): t = self.scheduler.now() + 20 m = Event(self, self, t, job = None, event = "triggerMaint") self.scheduler.add(m) def startmaint(self): #if self.activejob:9 # self.interuptJob() self.nummaint +=1 self.scheduler.deleteEvent('repair') self.scheduler.deleteEvent('fail') t = self.scheduler.now() + 10 m = Event(self, self, t, job = None, event = "maintStop") self.scheduler.add(m) def maintStop(self, temp): if not(self.scheduler.completed): self.generateFailure() self.generateMaintenance() self.maintcpl() if self.interuptjob: self.resumejob() elif self.queue: job = self.queue.pop(0) self.start(job) else: pass def triggerMaint(self, temp): if self.state == 'Up': self.maint() elif self.state == 'Failed': self.interrep() elif self.state == 'Blocked': print('onmogelijk!') #self.prevState = 'Maintenance' else: raise Exception('Foutje!') # Maintenance def storeState(self): self.prevState = self.states def arrive(self, m): self.arrivalInit(m) if self.busyServers < self.numServers and self.state == 'Up': self.busyServers += 1 self.start(m.job) else: self.queue.add(m.job) ##### End process logic ##### def receive(self, m): result = getattr(self, m.event)(m) ## Interupt and resume jobs ## def interuptJob(self): self.interuptjob = self.activejob self.activejob = None self.scheduler.deleteJob(self.interuptjob) def resumejob(self): self.activejob = self.interuptjob self.interuptjob = None t = self.scheduler.now() + self.activejob.serviceTime m = Event(self, self, t, job = self.activejob, event = "end") self.scheduler.add(m) ## Interupt and resume jobs ## def arrivalInit(self, m): self.jobsarrived += 1 job = m.job job.setArrivalTime(self.scheduler.now()) serviceTime = self.serviceTimeDistribution.rvs() job.setServiceTime(serviceTime) job.log(self.scheduler.now(), "a", self.busyServers + len(self.queue)) def send(self, job): # job departure job.log(self.scheduler.now(), "d", len(self.queue)) #print(len(self.queue)) m = Event(self, self.Out, self.scheduler.now(), job = job, event = "arrive") self.scheduler.add(m) def setServiceTimeDistribution(self, distribution): self.serviceTimeDistribution = distribution