Example #1
0
 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
Example #2
0
 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]
Example #3
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
Example #4
0
    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))
Example #5
0
 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
Example #6
0
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
Example #7
0
    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
Example #8
0
 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)
Example #9
0
    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))
Example #10
0
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
Example #11
0
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)
Example #14
0
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)
Example #15
0
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
Example #16
0
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
Example #17
0
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)
Example #18
0
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
Example #20
0
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
Example #21
0
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()
Example #22
0
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
Example #23
0
File: u.py Project: rpearl/advent
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
Example #24
0
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
Example #25
0
    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
Example #26
0
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
Example #27
0
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
Example #30
0
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))
Example #32
0
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()
Example #33
0
            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
Example #34
0
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