Example #1
0
def a_star(starting_node, target_node, paths):
    """
    A Star generic implementation (see https://en.wikipedia.org/wiki/A*_search_algorithm for more information)
    Finds a way from start to target by using the real cost of travelling and the heuristic values to determine a short path.
    :param starting_node: starting node
    :param target_node: target node
    :param paths: paths
    :return: ordered list of nodes leading to our goal.
    """
    closed = list()  # list that contains all visited nodes
    fringe = SortedList()  # contains all found nodes
    fringe.append(starting_node)  # append the starting node

    while True:
        if (len(fringe) == 0):  # if the fringe is empty
            return None
        node = fringe.pop(0)
        if not any(node.id == it.id for it in closed):  # if the current node is not in our closed list do:
            # print("Current Node= {}, Fringe={}".format(node,fringe)) - uncomment to see how it works!
            if (goal_check(node, target_node)):  # if the current node is our target find the path
                return find_solution(node)
            else:  # else find all neighboring nodes of the current node and add them to the fringe, finally add the curr node to closed.
                connected_nodes = get_connected_nodes(node, paths)
                for connected_node in connected_nodes:
                    fringe.add(connected_node)
                closed.append(node)
        else:
            print("skipped node={}".format(node))
Example #2
0
def get_top_pageranks(inlinks, outlinks, b, n=50, iters=20):
    """
    >>> inlinks = SortedDict({'a': ['c'], 'b': set(['a']), 'c': set(['a', 'b'])})
    >>> outlinks = SortedDict({'a': ['b', 'c'], 'b': set(['c']), 'c': set(['a'])})
    >>> res = get_top_pageranks(inlinks, outlinks, b=.5, n=2, iters=1)
    >>> len(res)
    2
    >>> res[0]  # doctest:+ELLIPSIS
    ('a', 0.6666...
    """
    res = []
    urls = SortedList()

    for out in outlinks:
        urls.append(out)

    pagerank = compute_pagerank(urls, inlinks, outlinks, b, iters)

    for num in range(n):
        temp = 0
        temp_u = ''
        for u in pagerank:
            if temp < pagerank[u] and u not in res:
                temp = pagerank[u]
                temp_u = u
        res.append((temp_u, temp))
        pagerank.pop(temp_u)

    return res
Example #3
0
def join_sections(sections):
    if isinstance(sections, SortedList):
        result_sections = SortedList(key=attrgetter("start_address"))
    else:
        result_sections = []
    prev_section = Section()
    while sections:
        section = sections.pop(0)
        if not isinstance(section, Section):
            raise TypeError("'{}' is not a 'Section' instance", section)
        if section.start_address == prev_section.start_address + prev_section.length and result_sections:
            last_segment = result_sections[-1]
            last_segment.data.extend(section.data)
            last_segment.length += section.length
        else:
            # Create a new section.
            if isinstance(sections, SortedList):
                result_sections.add(
                    Section(section.start_address, section.data))
            else:
                result_sections.append(
                    Section(section.start_address, section.data))
        prev_section = section
    if result_sections:
        return result_sections
    else:
        if isinstance(sections, SortedList):
            return SortedList(key=attrgetter("start_address"))
        else:
            return []
def test_append():
    slt = SortedList(load=17)

    slt.append(0)

    for val in range(1, 1000):
        slt.append(val)
        slt._check()
Example #5
0
def test_append():
    slt = SortedList(load=17)

    slt.append(0)

    for val in range(1, 1000):
        slt.append(val)
        slt._check()
Example #6
0
class MySorted:
    def __init__(self):
        self.elements = SortedList()

    def index(self, val):
        if not self.elements or self.elements[0] >= val:
            return 0
        elif self.elements[-1] <= val:
            return len(self.elements)
        return self.elements.index(val)

    def append(self, val):
        self.elements.append(val)

    def __len__(self):
        return len(self.elements)
Example #7
0
def generateTestData(queryPositivePercentage, sampleSize, maxUniverse):
    uncompressedList = []
    queryList = SortedList([])
    negativeList = []
    samplePercentage = sampleSize / maxUniverse * 100
    random.seed(datetime.now())
    for x in range(1, maxUniverse):
        if (random.randint(1, 100) <= samplePercentage):
            uncompressedList.append(x)
            if (random.randint(1, 100) <= queryPositivePercentage):
                queryList.append(x)
            elif (len(negativeList) > 0):
                # you add some random element from the negative list
                randomIndex = random.randrange(len(negativeList))
                queryList.add(negativeList.pop(randomIndex))
        else:
            negativeList.append(x)
    return (uncompressedList, list(queryList.islice(0, len(queryList))))
def test_append_valueerror():
    slt = SortedList(range(100))
    slt.append(5)
Example #9
0
def test_append_valueerror():
    slt = SortedList(range(100))
    slt.append(5)
class Genetic_algorithm(object):
    def __init__(self,
                 goal: object,
                 goal_score: int,
                 max_number_of_children: int,
                 population_limit: int,
                 crossover_chromosoma_probability: float,
                 tournament_size: int,
                 mutation_probability: float,
                 mutation_chromosoma_probability: float,
                 max_pixel_value: int,
                 strongest_rate=0.2):
        self.__goal = goal
        self.__goal_score = goal_score
        self.__number_of_chromosomes = len(goal)
        self.__population = SortedList()
        self.__new_population = queue.Queue()
        self.__population_limit = population_limit
        self.__tournament_size = tournament_size
        self.__crossover_chromosoma_probability = crossover_chromosoma_probability
        self.__mutation_probability = mutation_probability
        self.__mutation_chromosoma_probability = mutation_chromosoma_probability
        self.__strongest_limit = strongest_rate * population_limit
        self.__max_number_of_children = max_number_of_children
        self.__high_boundary_of_pixel = max_pixel_value + 1

    def run_algorithm(self):
        self.__generate_initial_population()
        self.__recombination()
        is_solved = self.__evaluate()
        while not is_solved:
            winners = self.__selection()
            self.__new_population = queue.Queue(self.__crossover(winners))
            self.__mutation()
            self.__recombination()
            is_solved = self.__evaluate()

    def __selection_tournament(self):
        selected_individuals = queue.Queue(
            random.sample(self.__population[:self.__strongest_limit],
                          self.__tournament_size))
        winners = queue.Queue()
        while (len(selected_individuals) > 1):
            individual_A = selected_individuals.get()
            individual_B = selected_individuals.get()

            if (individual_A > individual_B):
                winners.put(individual_A)
            else:
                winners.put(individual_B)
        return winners

    def __crossover(self, winners):
        winners_shuffle = queue.Queue(
            random.sample(self.__population[:self.__strongest_limit],
                          self.__tournament_size))

        while (not winners_shuffle.empty()):
            individual_A = winners_shuffle.get()
            individual_B = winners_shuffle.get()

            number_of_children = random.uniform(0,
                                                self.__max_number_of_children)
            children = list()
            [
                children.update(
                    self.__crossover_individuals(individual_A, individual_B))
                in range(number_of_children)
            ]
        return children

    def __crossover_individuals(self, individual_A, individual_B):
        children_list = list()
        for chromosoma_A, chromosoma_B in zip(individual_A.get_dna(),
                                              individual_B.get_dna()):
            is_crossover = random.uniform(
                0, 1) < self.__crossover_chromosoma_probability

            if is_crossover:
                new_chromosoma = (chromosoma_A + chromosoma_B) * 0.5
                children_list.append(new_chromosoma)
            else:
                chromosoma_to_add = chromosoma_A if random.uniform(
                    0, 1) < 0.5 else chromosoma_B
                children_list.append(chromosoma_to_add)
        return Individual(np.array(children_list))

    def __mutation(self):
        for individual in self.__population:
            is_mutation = random.uniform(
                0, self.__high_boundary_of_pixel) < self.__mutation_probability

            if is_mutation:
                self.__new_population.put(self.__mutate_individual(individual))

    def __mutate_individual(self, individual):
        mutated_individual = list()
        for chromosoma in enumerate(individual.get_dna()):
            is_mutation_chromosoma = random.uniform(
                0, 1) < self.__mutation_chromosoma_probability

            if is_mutation_chromosoma:
                mutated_individual.append(
                    random.uniform(0, self.__high_boundary_of_pixel))
            else:
                mutated_individual.append(chromosoma)
        return Individual(np.array(mutated_individual))

    def __recombination(self):
        while not self.__new_population.empty():
            new_individual = self.__new_population.get()
            new_individual.set_score(
                self.__evaluate_individual(new_individual))
            self.__population.append(new_individual)

        self.__population = self.__population[self.__population_limit:]

    def __evaluate_individual(self, individual):
        return np.sum(np.abs(np.subtract(individual.get_dna(), self.__goal)))

    def __evaluate(self):
        return self.__population[0].get_score() < self.__goal_score

    def __generate_initial_population(self):
        for i in range(self.__population_limit):
            new_dna = np.random.randint(self.__max_pixel_value,
                                        size=self.__image_goal.shape)
            new_individual = Individual(new_dna)
            self.__new_population.put(new_individual)
class Construe(object):
    """
    This class implements the **kardioml.segmentation.teijeiro.* algorithm allowing fine-grained
    control of the steps of the algorithm.
    """

    def __init__(self, root_node, K):
        """
        Initializes a new algorithm execution, receiving as arguments the
        root node for the exploration and the K parameter, which determines the
        exploratory nature of the algorithm.

        Instance Properties
        -------------------
        K:
            Exploration parameter.
        successors:
            Dictionary storing the successor generator of each node.
        last_time:
            Interpretation time of the most advanced interpretation generated
            so far.
        open:
            Sorted list of the open nodes, that can still be expanded.
        closed:
            Sorted list of closed nodes.
        best:
            When a node satisfies the *goal()* function, this attribute is
            assigned to that node. While the finished() method returns False,
            this attribute may be refined with new better interpretations.
        """
        assert K > 0
        self.K = K
        self.root = root_node
        self.successors = weakref.WeakKeyDictionary()
        root_succ = PredictableIter(reasoning.firm_succ(root_node))
        if not root_succ.hasnext():
            raise ValueError('The root node does not have valid successors')
        self.successors[root_node] = root_succ
        self.last_time = root_node.time_point
        ocov, scov, nhyp = valuation(root_node)
        heur = Heuristic(ocov, scov, -self.last_time, nhyp)
        self.open = SortedList([Node(heur, root_node)], key=attrgetter('h'))
        self.closed = SortedList(key=attrgetter('h'))
        self.best = None

    def _update_closed(self, newclosed):
        """
        Updates the *closed* list after an iteration of the algorithm. All
        closed interpretations but the best one are removed from this list.
        """
        if not newclosed:
            return
        tmplst = SortedList(key=attrgetter('h'))
        for lst in (newclosed, self.closed):
            for (ocov, scov, ntime, nhyp), n in lst:
                if -ntime < self.last_time:
                    ocov, scov, nhyp = valuation(n, self.last_time)
                tmplst.add(Node(Heuristic(ocov, scov, ntime, nhyp), n))
        self.closed.clear()
        self.closed.append(tmplst.pop(0))

    def step(self, filt=lambda _: True):
        """
        Performs a new step of the algorithm, by continuing the K-best nodes
        satisfying the *filt* function one step.

        Parameters
        ----------
        filt:
            Boolean function that receives an element of the open list and
            decides if the node can be expanded in this iteration. The first
            K nodes satisfying this filter are expanded.
        """
        newopen = []
        newclosed = []
        ancestors = set()
        optimal = False

        for _ in range(self.K):
            node = next((n for n in self.open if filt(n) and not (optimal and n.node in ancestors)), None)
            # The search stops if no nodes can be expanded or if, being in an
            # optimal context, we need to expand a non-optimal node.
            if node is None or (optimal and node.h.ocov > 0.0):
                break
            self.open.remove(node)
            # Go a step further
            nxt = self.successors[node.node].next()
            self.successors[nxt] = PredictableIter(reasoning.firm_succ(nxt))
            nxtime = nxt.time_point
            if nxtime > self.last_time:
                self.last_time = nxtime
            ocov, scov, nhyp = valuation(nxt, nxtime)
            nxt = Node(Heuristic(ocov, scov, -nxtime, nhyp), nxt)
            # Optimality is determined by the coverage of the successors.
            optimal = optimal or ocov == 0.0
            # Reorganize the open and closed list.
            for n in (node, nxt):
                if self.successors[n.node].hasnext():
                    newopen.append(n)
                    reasoning.save_hierarchy(n.node, ancestors)
                else:
                    newclosed.append(n)
                    if (
                        n is nxt
                        and n.h.ocov == 0.0
                        and goal(n.node)
                        and (self.best is None or n.h < self.best.h)
                    ):
                        self.best = n
        for node in newopen:
            self.open.add(node)
        # The closed list is recalculated by keeping only the best one.
        self._update_closed(newclosed)
        if not self.open:
            if not self.closed:
                raise ValueError('Could not find a complete interpretation.')
            self.best = min(self.closed)

    def prune(self):
        """
        Perform a pruning operation by limiting the size of the *open* list
        only to the K best.
        """
        # Now we get the best nodes with a common valuation.
        newopened = SortedList(key=attrgetter('h'))
        for h, node in self.open:
            ocov, scov, nhyp = valuation(node, self.last_time)
            newopened.add(Node(Heuristic(ocov, scov, h.time, nhyp), node))
        self.open = newopened
        n = min(len(self.open), self.K)
        if not reasoning.SAVE_TREE:
            # We track all interesting nodes in the hierarchy.
            saved = set()
            stop = set()
            for i in range(n):
                node = self.open[i].node
                reasoning.save_hierarchy(node, saved)
                stop.add(node)
                mrg = reasoning._MERGED.get(node)
                if mrg is not None:
                    reasoning.save_hierarchy(mrg, saved)
                    stop.add(mrg)
            for _, node in self.closed:
                reasoning.save_hierarchy(node, saved)
            if self.best is not None:
                reasoning.save_hierarchy(self.best.node, saved)
            # And we prune all nodes outside the saved hierarchy
            stack = [self.root]
            while stack:
                node = stack.pop()
                if node not in saved:
                    node.discard('Sacrificed interpretation')
                elif node not in stop:
                    stack.extend(node.child)
        del self.open[n:]
        # We also clear the reasoning cache, since some interpretations cannot
        # be eligible for merging anymore.
        if self.open:
            earliestime = min(n.past_metrics.time for _, n in self.open)
            reasoning.clear_cache(earliestime)

    def finished(self):
        """
        Checks if the searching procedure is finished, that is, more
        iterations, even if possible, will probably not lead to better
        interpretations that the best one. This is considered true if in the
        open list there are no partial covers with less hypotheses than
        the current best interpretation and that are not ancestors of the
        current best interpretation.
        """
        return self.best is not None and all(
            self.best.node.is_ancestor(n.node)
            for n in self.open
            if n.h.ocov == 0.0 and n.h.nhyp < self.best.h.nhyp
        )
Example #12
0
class GreedyTaskQueue(TaskQueue):
    """Describes a greedy task queue, which prioritizes tasks with the highest
    number of cores.

    :ivar int total_cores: if the cores on a task is None, we assume it is
        going to require this many cores.
    :ivar dict[int, list[Task]] tasks_by_core: a lookup for remaining tasks,
        where the key is the number of cores the task requires.
    :ivar SortedList[int] sorted_keys: the keys for tasks_by_core in
        ascending order.
    :ivar bool expecting_more_tasks: if True, we expect that add_task will be
        called in the (near) future, hence we always return True from
        have_more_tasks
    :ivar int _len: the length of this queue
    """
    def __init__(self, total_cores: int):
        """Initializes an empty task queue."""
        self.total_cores = total_cores
        self.tasks_by_core = dict()
        self.sorted_keys = SortedList()
        self.expecting_more_tasks = False
        self._len = 0

    def flatten(self) -> typing.List[Task]:
        """Returns this task queue as a list of tasks.
        """
        res = []
        for v in self.tasks_by_core.values():
            res.extend(v)
        return res

    def set_total_cores(self, total_cores):
        old_total = self.total_cores
        self.total_cores = total_cores
        if len(self.sorted_keys) == 0:
            return
        if old_total < total_cores:
            flat = self.flatten()
            self.sorted_keys = SortedList()
            self.tasks_by_core = dict()
            self._len = 0
            self.add_tasks(flat)
            return

        arrs = []
        while self.sorted_keys[-1] > self.total_cores:
            k = self.sorted_keys.pop()
            arrs.append(self.tasks_by_core[k])
            del self.tasks_by_core[k]

        if not self.sorted_keys:
            self.sorted_keys.append(self.total_cores)
            self.tasks_by_core[self.total_cores] = []

        last = self.tasks_by_core[self.sorted_keys[-1]]
        for arr in arrs:
            last.extend(arr)

    def add_task(self, task: Task) -> None:
        """Adds the given task to this queue."""
        cores_req = self.total_cores
        if task.cores is not None:
            cores_req = min(task.cores, self.total_cores)

        arr = self.tasks_by_core.get(cores_req)
        if arr is None:
            arr = []
            self.tasks_by_core[cores_req] = arr
            self.sorted_keys.add(cores_req)
        arr.append(task)
        self._len += 1

    def add_tasks(self, tasks: typing.Iterable[Task]) -> None:
        """Adds all the specified tasks to this queue."""
        for task in tasks:
            self.add_task(task)

    def get_next_task(self, cores: int):
        prev = None
        for k in self.sorted_keys:
            if k > cores:
                break
            prev = k

        if prev is None:
            return None

        arr = self.tasks_by_core[prev]
        res = arr.pop()
        self._len -= 1
        if not arr:
            del self.tasks_by_core[prev]
            self.sorted_keys.remove(prev)
        return res

    def have_more_tasks(self):
        return not self.expecting_more_tasks and len(self.sorted_keys) > 0

    def __len__(self):
        return self._len