コード例 #1
0
def test_eq():
    alpha = SortedSet(range(100), load=7)
    beta = SortedSet(range(100), load=17)
    assert alpha == beta
    assert alpha == beta._set
    beta.add(101)
    assert not (alpha == beta)
コード例 #2
0
ファイル: pagerank.py プロジェクト: setr/cs429
def get_links(names, html):
    """
    Return a SortedSet of computer scientist names that are linked from this
    html page. The return set is restricted to those people in the provided
    set of names.  The returned list should contain no duplicates.

    Params:
      names....A SortedSet of computer scientist names, one per filename.
      html.....A string representing one html page.
    Returns:
      A SortedSet of names of linked computer scientists on this html page, restricted to
      elements of the set of provided names.

    >>> get_links({'Gerald_Jay_Sussman'},
    ... '''<a href="/wiki/Gerald_Jay_Sussman">xx</a> and <a href="/wiki/Not_Me">xx</a>''')
    SortedSet(['Gerald_Jay_Sussman'], key=None, load=1000)
    """

    pagenames = SortedSet()
    for link in BeautifulSoup(html, "html.parser", parse_only=SoupStrainer('a')):
        if link.has_attr('href'):
            name = link['href'].split('/')[-1]
            if name in names:
                pagenames.add(name)
    return pagenames
コード例 #3
0
def test_ne():
    alpha = SortedSet(range(100), load=7)
    beta = SortedSet(range(99), load=17)
    assert alpha != beta
    beta.add(100)
    assert alpha != beta
    assert alpha != beta._set
コード例 #4
0
def get_links(names, html):
    """
    Return a SortedSet of computer scientist names that are linked from this
    html page. The return set is restricted to those people in the provided
    set of names.  The returned list should contain no duplicates.

    Params:
      names....A SortedSet of computer scientist names, one per filename.
      html.....A string representing one html page.
    Returns:
      A SortedSet of names of linked computer scientists on this html page, restricted to
      elements of the set of provided names.

    >>> get_links({'Gerald_Jay_Sussman'},
    ... '''<a href="/wiki/Gerald_Jay_Sussman">xx</a> and <a href="/wiki/Not_Me">xx</a>''')
    SortedSet(['Gerald_Jay_Sussman'], key=None, load=1000)
    """
    soup = BeautifulSoup(html,"html.parser")
    list = [l['href'] for l in soup.find_all('a') if l.get('href')]
    res = SortedSet()
    for l in list:
        if l.startswith('/wiki/'):
            tokens = l.split('/')
            if tokens[2] in names:
                res.add(tokens[2])
    
    return res
コード例 #5
0
def test_add():
    temp = SortedSet(range(100))
    temp._reset(7)
    temp.add(100)
    temp.add(90)
    temp._check()
    assert all(val == temp[val] for val in range(101))
コード例 #6
0
def test_count():
    temp = SortedSet(range(100), load=7)
    assert all(temp.count(val) == 1 for val in range(100))
    assert temp.count(100) == 0
    assert temp.count(0) == 1
    temp.add(0)
    assert temp.count(0) == 1
    temp._check()
コード例 #7
0
def test_eq():
    alpha = SortedSet(range(100))
    alpha._reset(7)
    beta = SortedSet(range(100))
    beta._reset(17)
    assert alpha == beta
    assert alpha == beta._set
    beta.add(101)
    assert not (alpha == beta)
コード例 #8
0
class DictGraph(Graph):
    """Graph that supports nonconsecutive vertex ids."""

    def __init__(self, nodes: Set[int]=None, r: int=1) -> None:
        """Make a new graph."""
        if nodes is None:
            self.nodes = SortedSet()  # type: Set[int]
        else:
            self.nodes = nodes
        self.radius = r
        self.inarcs_by_weight = [defaultdict(SortedSet) for _ in range(self.radius)]

    def __len__(self):
        """len() support."""
        return len(self.nodes)

    def __iter__(self):
        """Iteration support."""
        return iter(self.nodes)

    def __contains__(self, v):
        """Support for `if v in graph`."""
        return v in self.nodes

    def add_node(self, u: int):
        """Add a new node."""
        self.nodes.add(u)

    def arcs(self, weight: int=None):
        """
        Return all the arcs in the graph.

        restrict to a given weight when provided
        """
        if weight:
            return [(x, y) for x in self.nodes
                    for y in self.inarcs_by_weight[weight-1][x]]
        else:
            return [(x, y, w+1) for w, arc_list in
                    enumerate(self.inarcs_by_weight)
                    for x in self.nodes
                    for y in arc_list[x]]

    def remove_isolates(self) -> List[int]:
        """
        Remove all isolated vertices and return a list of vertices removed.

        Precondition:  the graph is bidirectional
        """
        isolates = [v for v in self if self.in_degree(v, 1) == 0]
        for v in isolates:
            self.nodes.remove(v)
            for N in self.inarcs_by_weight:
                if v in N:
                    del N[v]
        return isolates
コード例 #9
0
def test_ne():
    alpha = SortedSet(range(100))
    alpha._reset(7)
    beta = SortedSet(range(99))
    beta._reset(17)
    assert alpha != beta
    beta.add(100)
    assert alpha != beta
    assert alpha != beta._set
    assert alpha != list(range(101))
コード例 #10
0
ファイル: pagerank.py プロジェクト: BrindaRao/IR_Assignments
def get_links(names, html):
    """
    Return a SortedSet of computer scientist names that are linked from this
    html page. The return set is restricted to those people in the provided
    set of names.  The returned list should contain no duplicates.

    Params:
      names....A SortedSet of computer scientist names, one per filename.
      html.....A string representing one html page.
    Returns:
      A SortedSet of names of linked computer scientists on this html page, restricted to
      elements of the set of provided names.

    >>> get_links({'Gerald_Jay_Sussman'},
    ... '''<a href="/wiki/Gerald_Jay_Sussman">xx</a> and <a href="/wiki/Not_Me">xx</a>''')
    SortedSet(['Gerald_Jay_Sussman'], key=None, load=1000)
    """
    ###TODO
    #remove BeautifulSoap - later


    listofHrefs = []
    listofHrefTexts = []
    FinalSortedSet = SortedSet()
    splice_char = '/'
    #getting all the tags using the BeautifulSoup
    #soup = BeautifulSoup(html, "html.parser") 
    #fectching all the links in anchor tags
    #for link in soup.find_all('a'):
        #listofHrefs.append(link.get('href'))
    for i in range(0,len(listofHrefs)):
        value = listofHrefs[i][6:]
        listofHrefTexts.append(value)
    listofHrefTexts = re.findall(r'href="([^"]*)', html)
    #print(listofHrefTexts)
    for i in listofHrefTexts:
        #print(i)
        value = i[6:]
        listofHrefs.append(value)
    #print(listofHrefs)
    listofHrefs = list(set(listofHrefs))
    #print(len(listofHrefs))
    for href in listofHrefs:
        for name in names:
            #windows OS handling
            if(name == "Guy_L._Steele,_Jr"):
                names.remove(name)
                names.add("Guy_L._Steele,_Jr.")
            if(href == name):
                FinalSortedSet.add(name)
            
    
    return FinalSortedSet
    
    pass
コード例 #11
0
def compute_domset(graph: Graph, radius: int):
    """
    Compute a d-dominating set using Dvorak's approximation algorithm
    for dtf-graphs (see `Structural Sparseness and Complex Networks').
    Graph needs a distance-d dtf augmentation (see rdomset() for usage).
    """
    domset = SortedSet()
    infinity = float('inf')
    # minimum distance to a dominating vertex, obviously infinite at start
    domdistance = defaultdict(lambda: infinity)  # type: Dict[int, float]
    # counter that keeps track of how many neighbors have made it into the
    # domset
    domcounter = defaultdict(int)  # type: Dict[int, int]
    # cutoff for how many times a vertex needs to have its neighbors added to
    # the domset before it does.  We choose radius^2 as a convenient "large"
    # number
    c = (2*radius)**2

    # Sort the vertices by indegree so we take fewer vertices
    order = sorted([v for v in graph], key=lambda x: graph.in_degree(x),
                   reverse=True)
    # vprops = [(v,graph.in_degree(v)) for v in nodes]
    # vprops.sort(key=itemgetter(1),reverse=False)
    # order = map(itemgetter(0),vprops)

    for v in order:
        # look at the in neighbors to update the distance
        for r in range(1, radius + 1):
            for u in graph.in_neighbors(v, r):
                domdistance[v] = min(domdistance[v], r+domdistance[u])

        # if v is already dominated at radius, no need to work
        if domdistance[v] <= radius:
            continue

        # if v is not dominated at radius, put v in the dominating set
        domset.add(v)
        domdistance[v] = 0

        # update distances of neighbors of v if v is closer if u has had too
        # many of its neighbors taken into the domset, include it too.
        for r in range(1, graph.radius + 1):
            for u in graph.in_neighbors(v, r):
                domcounter[u] += 1
                domdistance[u] = min(domdistance[u], r)
                if domcounter[u] > c and u not in domset:
                    # add u to domset
                    domset.add(u)
                    domdistance[u] = 0
                    for x, rx in graph.in_neighbors(u):
                        domdistance[x] = min(domdistance[x], rx)
                # only need to update domdistance if u didn't get added

    return domset
コード例 #12
0
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
コード例 #13
0
ファイル: euler071.py プロジェクト: mertcanekiz/Euler
def euler():
    fracs = SortedSet()
    limit = 10**6
    for d in range(5, limit+1):
        target = d*3/7
        for n in range(int(floor(target)), int(ceil(target))+1):
            if gcd(n, d) == 1:
                fracs.add(Fraction(n, d))
    result = 0
    compare = Fraction(3, 7)
    for i, f in enumerate(fracs):
        if f == compare:
            result = i-1
            break
    print(fracs[result])
コード例 #14
0
ファイル: cache.py プロジェクト: AKSW/QuitStore
class FileReference:
    """A class that manages n-triple files.
    This class stores inforamtation about the location of a n-triple file and is
    able to add and delete triples to that file.
    """

    def __init__(self, path, content):
        """Initialize a new FileReference instance.
        Args:
            filelocation: A string of the filepath.
            filecontentinmem: Boolean to decide if local filesystem should be used to
                or if file content should be kept in memory too . (Defaults false)
        Raises:
            ValueError: If no file at the filelocation, or in the given directory + filelocation.
        """

        if isinstance(content, str):
            new = []
            for line in content.splitlines():
                new.append(' '.join(line.split()))
            content = new

        self._path = path
        self._content = SortedSet(content)
        self._modified = False

    @property
    def path(self):
        return self._path

    @property
    def content(self):
        return "\n".join(self._content) + "\n"

    def add(self, data):
        """Add a triple to the file content."""
        self._content.add(data)

    def extend(self, data):
        """Add triples to the file content."""
        self._content.extend(data)

    def remove(self, data):
        """Remove trple from the file content."""
        try:
            self._content.remove(data)
        except KeyError:
            pass
コード例 #15
0
ファイル: euler050.py プロジェクト: mertcanekiz/Euler
def euler50():
    limit = 100
    primes = SortedSet(sieve.primerange(1, limit))
    prime_sums = SortedSet()
    prime_sums.add(0)
    consecutive = 0
    for p in primes:
        prime_sums.add(prime_sums[-1] + p)
    for i in range(consecutive, len(prime_sums)):
        for j in range(i - consecutive - 1, -1, -1):
            if prime_sums[i] - prime_sums[j] > limit:
                break
            if isprime(prime_sums[i] - prime_sums[j]):
                consecutive = i - j
                result = prime_sums[i] - prime_sums[j]
    print(result)
コード例 #16
0
def reduce(stdin):
    current_key = None
    neighbors = SortedSet()

    for line in stdin:
        #bye bye whitespace
        line = line.strip()
        # parse the mapper input
        key, friend = line.split('\t', 1)
        if current_key == key:
            neighbors.add(friend)
        else:
            if current_key:
                yield '%s\t%s' % (current_key, '\t'.join(neighbors))
                neighbors = SortedSet()
            current_key = key
            neighbors.add(friend)
    #make sure to include the last entry
    yield '%s\t%s' % (current_key, '\t'.join(neighbors))
コード例 #17
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...
    """
    urls = SortedSet()
    
    for value in inlinks:
        urls.add(value)
    
    for value in outlinks:
        urls.add(value)
    
    Score = compute_pagerank(urls, inlinks, outlinks, b, iters)
    
    return sorted(Score.items(),key=lambda x:x[1],reverse=True)[:n]
コード例 #18
0
ファイル: Scrapper.py プロジェクト: hermes95/GoldwasserRsrch
def get_members(num_pages=20):
    """
    Goes to the top 20 pages of member listings, and get's em all
    :param num_pages:
    :return:
    """
    all_members = SortedSet()
    for page_num in range(1, num_pages):
        this_page = urllib.urlopen(root + route_people + '&page=' + str(page_num)).read()
        this_page_soup = BeautifulSoup(this_page, 'lxml')

        members_on_this_page = this_page_soup.find_all('div', class_='member')
        # -- Goes over all members in the page, and adds em to the set -- #
        for member in members_on_this_page:
            member_url = member.find('div', class_='pic').a['href']
            member_obj = get_member_with_url(str(member_url))
            print member_obj.username
            all_members.add(member_obj)
            if len(all_members) % 10 == 0:
                write_to_file(list(all_members[:-10]), 'all_members.txt', _MemberEncoder, False)
    return all_members
コード例 #19
0
ファイル: common.py プロジェクト: oar-team/batsim
def take_first_resources(available_res, nb_res_to_take):
    """Take the first nb_res_to_take resources into available_res."""
    if nb_res_to_take > len(available_res):
        raise Exception('Invalid schedule. Want to use {} resources whereas '
                        'only {} are available({})'.format(nb_res_to_take,
                                                           len(available_res),
                                                           available_res))
    allocation = SortedSet()
    l = list(available_res)

    for i in range(nb_res_to_take):
        allocation.add(l[i])

    available_res.difference_update(allocation)

    if len(available_res) > 0:
        min_available_res = min(available_res)
        for res in allocation:
            if res >= min_available_res:
                raise Exception('Invalid sort')

    return (available_res, allocation)
コード例 #20
0
def get_links(names, html):
    """
    Return a SortedSet of computer scientist names that are linked from this
    html page. The return set is restricted to those people in the provided
    set of names.  The returned list should contain no duplicates.

    Params:
      names....A SortedSet of computer scientist names, one per filename.
      html.....A string representing one html page.
    Returns:
      A SortedSet of names of linked computer scientists on this html page, restricted to
      elements of the set of provided names.

    >>> get_links({'Gerald_Jay_Sussman'},
    ... '''<a href="/wiki/Gerald_Jay_Sussman">xx</a> and <a href="/wiki/Not_Me">xx</a>''')
    SortedSet(['Gerald_Jay_Sussman'], key=None, load=1000)
    """
    ###TODO
    
    my_set = SortedSet()
    soup = BeautifulSoup(html,'lxml')
    
    for link in soup.find_all('a'):
    	
    	if link.get('href'):
    		
    		count = 0
    		for page in names:	
    			if count == 0:
    				if '/wiki/'+page == link['href']:
    					count = 1
    					my_set.add(page)
    			# to early terminate
    			elif count == 1:
    				break
    ###
    
    return my_set
コード例 #21
0
    def containsNearbyAlmostDuplicate(self, nums, k, t):
        """
        :type nums: List[int]
        :type k: int
        :type t: int
        :rtype: bool
        """
        if k < 1 or t < 0 or nums == None or len(nums) < 2:
            return False

        treeset = SortedSet()

        for i in xrange(len(nums)):
            # Solution 1
            subset = [x for x in treeset.irange(nums[i] - t, nums[i] + t)]
            if len(subset) > 0:
                return True
            treeset.add(nums[i])

            if i >= k:
                treeset.discard(nums[i - k])

        return False
コード例 #22
0
def test_stress(repeat=1000):
    sst = SortedSet(range(1000))

    for rpt in range(repeat):
        action = random.choice(actions)
        action(sst)

        try:
            sst._check()
        except AssertionError:
            print(action)
            raise

        start_len = len(sst)

        while len(sst) < 500:
            sst.add(random.randrange(0, 2000))

        while len(sst) > 2000:
            del sst[random.randrange(0, len(sst))]

        if start_len != len(sst):
            sst._check()
コード例 #23
0
ファイル: selection.py プロジェクト: Sebelino/pyromhackit
    def revealed2sortedset(revealed: List[Union[tuple, slice]]) -> SortedSet:
        """ Converts a list of included pairs to a sorted set of integers in O(n), n = size of @slices.
        Every number from every slice is added to the sorted set, except 0.
        """
        # 10, [] -> 10, []
        # 10, [(0, 10)] -> 10, [10]
        # 10, [(0, 7)] -> 10, [7]
        # 10, [(7, 10)] -> 10, [7, 10]
        # 10, [(3, 7)] -> 10, [3, 7]
        # 10, [(0, 3), (7, 10)] -> 10, [3, 7, 10]
        # 10, [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] -> 10, [1, 2, 3, 4, 5, 6, 7, 8, 9]

        try:
            #intervals = SortedSet(a for a, _ in revealed).union(b for _, b in revealed)
            intervals = SortedSet()
            for a, b in revealed:
                intervals.add(a)
                intervals.add(b)
        except TypeError:  # slice
            intervals = SortedSet(sl.start for sl in revealed).union(sl.stop for sl in revealed)
        if 0 in intervals:
            intervals.remove(0)
        return intervals
コード例 #24
0
ファイル: solver.py プロジェクト: rogerfitz/optimization
def swapConnColors(c1, c2, ndx):
	#kempe chain connected
	new1 = SortedSet()
	new2 = SortedSet()

	for i in c1:
		swapped = False
		for j in ndx[i]:
			if j in c2:
				new1.add(j)
				new2.add(i)
				swapped = True
		if not swapped:
			new1.add(i)
			new2.add(j)		
	#print c1, c2
	#print new1, new2
	return new1,new2		
コード例 #25
0
def get_ready_steps(deps):
    ready = SortedSet()
    for step in deps:
        if not deps[step]:
            ready.add(step)
    return ready
コード例 #26
0
	first_repo = True
	print "Searching stash project[" + project["name"] + "]"
	for repo in stash.projects[project["key"]].repos.list():
		name = repo["name"].lower()
		if None == repositories or name in repositories:
			if first_repo:
				print ""
				first_repo = False

			print "Found repository[" + name + "]"
			repositories.remove(name)

			if os.path.exists(args.clone_directory + "/" + name):
				print name + " already cloned, continuing..."
				print ""
				repositories_already_cloned.add(name)
				continue

			for url in repo["links"]["clone"]:
				if (url["name"] == "ssh"):
					os.system("git clone " + url["href"] + " " + args.clone_directory + "/" + name)
					repositories_cloned.add(name)
					break

			print ""

print "\n\n*******************"
print "SUMMARY"
print "*******************"
print "Repositories Cloned:"
for s in repositories_cloned:
コード例 #27
0
def fetch_us_surnames(url_1990: str,
                      url_2010: str,
                      filename: str,
                      freq_csv_filename: str = "",
                      min_cumfreq_pct: float = 0,
                      max_cumfreq_pct: float = 100,
                      min_word_length: int = 1,
                      show_rejects: bool = False) -> None:
    """
    Fetches US surnames from the 1990 and 2010 census data. Writes them to a
    file.

    Args:
        url_1990:
            URL for 1990 US census data
        url_2010:
            URL for 2010 US census data
        filename:
            text filename to write names to (one name per line)
        freq_csv_filename:
            optional CSV to write "name, frequency" pairs to, one name per line
        min_cumfreq_pct:
            minimum cumulative frequency (%): 0 for no limit, or above 0 to
            exclude common names
        max_cumfreq_pct:
            maximum cumulative frequency (%): 100 for no limit, or below 100 to
            exclude rare names
        min_word_length:
            minimum word length; all words must be at least this long
        show_rejects:
            report rejected words to the Python debug log
    """
    nameinfo_p1 = (
        gen_name_info_via_min_length(
            gen_sufficiently_frequent_names(
                gen_us_surname_1990_info(
                    gen_lines_from_binary_files(
                        gen_binary_files_from_urls([url_1990])
                    )
                ),
                min_cumfreq_pct=min_cumfreq_pct,
                max_cumfreq_pct=max_cumfreq_pct,
                show_rejects=show_rejects
            ),
            min_name_length=min_word_length
        )
    )
    nameinfo_p2 = (
        gen_name_info_via_min_length(
            gen_sufficiently_frequent_names(
                gen_us_surname_2010_info(
                    gen_rows_from_csv_binfiles(
                        gen_files_from_zipfiles(
                            gen_binary_files_from_urls([url_2010],
                                                       on_disk=True),  # a zip
                            #  The zip file contains a .CSV and a .XLS
                            filespec="*.csv",
                            on_disk=True
                        ),
                        skip_header=True
                    )
                ),
                min_cumfreq_pct=min_cumfreq_pct,
                max_cumfreq_pct=max_cumfreq_pct,
                show_rejects=show_rejects
            ),
            min_name_length=min_word_length
        )
    )
    pipeline = itertools.chain(nameinfo_p1, nameinfo_p2)
    names = SortedSet()
    freq = {}  # type: Dict[str, float]
    for nameinfo in pipeline:
        name = nameinfo.name
        if name not in names:
            names.add(nameinfo.name)
            freq[name] = nameinfo.freq_p
    write_words_to_file(filename, names)
    if freq_csv_filename:
        log.info(f"Writing to: {freq_csv_filename}")
        with open(freq_csv_filename, "wt") as f:
            csvwriter = csv.writer(f)
            for name in names:
                csvwriter.writerow([name, freq[name]])
        log.info(f"... finished writing to: {freq_csv_filename}")
コード例 #28
0
    def readConfig(self, **task_options):
        """readConfig function for AverageCorrelators

    YAML:
      file_mode: overwrite  # optional

      off_diagonal: false
      hermitian: false

      # used for giving more details in averaged op name
      use_spatial_info: true
      use_irrep_info: true

      write_operators: false

      plot_info:
        corrname: standard                   # optional
        timestep: 3                          # optional
        rescale: 1.0                         # optional
        symbol_color: blue                   # optional
        symbol_type: circle                  # optional
        max_relative_error: 2.0              # optional
        effective_energy_type: time_forward  # optional

      coefficients:         # optional
        - operator: op_string
          coefficient: -92
        - ...
        ...

      # list of operators to exclude from averaging
      excluded_operators:
        - kbar S=1 P=(0,0,1) A2 k 0
        - ...

      averaged_channels:    # optional
        - isospin: quintet
          strangeness: 0
          momentum: [0,0,0]
          irrep: A1gp
        - ...
        ...
    """
        if 'averaged_channels' in task_options:
            averaged_channels = SortedSet()
            for averaged_channel in task_options.pop('averaged_channels'):
                averaged_channels.add(
                    operator_info.channel.Channel(**averaged_channel))
            task_options['averaged_channels'] = averaged_channels

        if 'coefficients' in task_options:
            coefficients = dict()
            for coefficient in task_options.pop('coefficients'):
                try:
                    operator = operator_info.operator.Operator(
                        coefficient.get('operator'))
                    coefficient = float(coefficient.get('coefficient'))
                except KeyError as err:
                    logging.error(
                        f"coefficients item missing required key '{err}'")

                coefficients[operator] = coefficient

            task_options['coefficients'] = coefficients

        if 'file_mode' in task_options:
            try:
                task_options['file_mode'] = sigmond.WriteMode.create(
                    task_options['file_mode'])
            except ValueError:
                logging.error(f"Invalid file_mode in '{self.task_name}'")

        excluded_operators = set()
        for excluded_operator in task_options.pop('excluded_operators', []):
            excluded_operators.add(
                operator_info.operator.Operator(excluded_operator))

        task_options['excluded_operators'] = excluded_operators

        task_options[
            'plot_info'] = sigmond_info.sigmond_info.PlotInfo.createFromConfig(
                task_options)

        self.initiliaze(**task_options)
コード例 #29
0
class SocialNetwork(object):
    ID = 0
    
    strategies = [COOP, DEFE]

    def __init__(self, 
                 fluct,
                 rep,
                 nt_seed,
                 nt_desc,
                 nt_randomseed,
                 coop_prob = JUST_COOPERATORS,
                 randomseed = None,
                 b=1,                   
                 n_per_gen=10, 
                 e_per_gen=2, 
                 epsilon = 0.99,
                 max=1000, 
                 tourn=0.01, 
                 X=0.025,
                 K=sys.maxsize,
                 X2= 0.025):

        # this is for identification of the network
        self.id = self.__class__.ID
        self.__class__.ID += 1
        self.fluct = fluct
             
        self.rep = rep
        self.nt_desc = nt_desc
        self.nt_randomseed = nt_randomseed
        self.coop_prob = coop_prob
        
        # set the PD game
        self.T = b
        self.R = 1
        self.P = 0
        self.S = 0               
        
        # seed for the network, this is useful to replicate exactly the same
        # experiment, particularly useful for debugging
        if randomseed == None:
            self.randomseed = time.time()
        else:
            print("WARNING: random seed is not null. Are you sure?")
            self.randomseed = randomseed
        random.seed(self.randomseed)
        
        # main parameters
        self.b = b
        self.n_per_gen = n_per_gen
        self.e_per_gen = e_per_gen
        if (epsilon >= 1.0):
            raise ValueError("""Epsilon cannot be bigger or equal to 1.0.
                             You can use epsilon that are similar to 1.0, 
                             e.g 0.999999999 """)
        else:
            self.epsilon = epsilon
        self.max = max
        self.tourn = tourn
        self.X = X
        self.K = K
        self.X2 = X2
        
        # counters
        self.gen = 0
        self.count = 0
        self.cooperators = 0
        self.removed_nodes = 0
        self.total_fit = 0
        self.total_efit = 0
        self.degrees = 0
        self.size = 0
        g = self.g = nx.Graph()

        # crate auxiliary network structures to increase efficiency
        self._max = max+n_per_gen
        self.eps_fitness = np.empty(self._max)
        self.degrees = np.empty(self._max)
        self.fitness = np.empty(self._max)
        self.fitness_of = np.empty(self._max, dtype=np.int_)
        self.free_indexes = []
        self.node_set = SortedSet()
        
        # initialize the auxiliary structures
        for i in range(0, self._max):
            self.degrees[i] = 0
            self.fitness_of[i] = -1
            self.free_indexes.append(i)
       
        # create the network 
        self.__create_from_seed(nt_seed, coop_prob)
        
        # define the game the nodes are going to play
        self.game = PD(b, self.fitness)
        
        self.treatment = '_'.join(str(x) for x in (self.nt_desc, 
                                                   self.coop_prob,
                                                   self.fluct, self.b,
                                                   self.X, self.K, self.X2))
        
        self.signature = str(self.id) + '_' + \
                         str(self.rep) + '(' + self.treatment + ')'
        

    def __create_from_seed(self, seed, coop_prob):
        """ This method use the networks structure that comes in the parameter 
        seed as a template for the graph. It adds the necessary attributes to 
        run the algorithm, such as which nodes are cooperators and defectors 
        based on the coop_prob parameter. A value from 0 to 1 indicating a 
        probability of any node of being a cooperators.
        
        Assumes that it is called from the constructor. So it assumes a new 
        SocialNetwork.
        """   
        self.count = -1
        g = self.g
        
        # add nodes from the seed to the network 
        for node in seed.nodes_iter(data = True):
            # define the attributes of the node 
            id = node[0]          
            if coop_prob == 1 or random.uniform(0,1) < coop_prob:
                st = COOP
                self.cooperators += 1
            else:
                st = DEFE
            r_index = self.free_indexes.pop()   
            
            # add the node
            g.add_node(id, st=st, nst=st, r_index=r_index)
            
            self.node_set.add(id)
            self.fitness_of[r_index] = id
            self.fitness[r_index] = 0
            
            # update parameters of the graph
            if id > self.count: 
                self.count = id
            self.size += 1

        self.count += 1
        
        # add edges from the seed to the network
        for e0, e1 in seed.edges_iter():
            g.add_edge(e0, e1)
            
        self.__remove_isolated_nodes()
        
    
    def __remove_isolated_nodes(self):
        g = self.g
        to_remove = []
        for n, adj in g.adj.items():
            if (len(adj) == 0):
                to_remove.append(n)
                
        for n in to_remove:
            r_index = g.node[n]['r_index']
            self.fitness_of[r_index] = -1
            self.free_indexes.append(r_index)
            self.node_set.discard(n)
            g.remove_node(n)
            self.size -= 1
    
    def add_node(self, st):
        """ Add a node to the network
        """
        # calculate rest of the node attributes
        id = self.count
        r_index = self.free_indexes.pop()
        
        # add node
        self.g.add_node(id, st=st, nst=st, r_index=r_index, gen=self.gen)
        
        # update network structures
        self.node_set.add(id)
        self.fitness_of[r_index] = id
        self.fitness[r_index] = 0
        self.degrees[r_index] = 0
        
        # update network parameters
        if st == COOP:
            self.cooperators += 1
        self.size += 1
        self.count += 1
        
        return id


    def play_games_and_remove_isolated_nodes(self):
        g = self.g
        node = g.node
        node_set = self.node_set
        adjacency = self.g.adj
        f = self.fitness
        ef = self.eps_fitness
        eps = self.epsilon
        degrees = self.degrees
                
        f.fill(0)

        total_fit = 0
        total_efit = 0
        total_degrees = 0
        to_remove=[]
        
        for n1 in node_set:
            adj = adjacency[n1]
            len_adj = len(adj)

            # make sure to remove the nodes that has no more edges
            if (len_adj == 0):
                to_remove.append(n1)
                self.removed_nodes += 1
            else:
                att1 = node[n1]
                r_index1 = att1['r_index']    
                
                #update the strategy
                n1_e = att1['st'] = att1['nst']
                                              
                # play against all the neighbors
                for n2 in adj.keys():
                    # make sure to play just once, nodes should be in order
                                    # make sure all the adjacent nodes are in order
                    
                    if (n2 > n1):
                        att2 = node[n2]
                        if n1_e == att2['nst']:
                            if n1_e == COOP:
                                f[r_index1] += self.R
                                f[att2['r_index']] += self.R
                                total_fit += self.R + self.R
                            else:
                                f[r_index1] += self.P
                                f[att2['r_index']] += self.P
                                total_fit += self.P + self.P
                        else:
                            if n1_e == COOP:
                                f[r_index1] += self.S
                                f[att2['r_index']] += self.T
                                total_fit += self.S + self.T
                            else:
                                f[r_index1] += self.T
                                f[att2['r_index']] += self.S
                                total_fit += self.T + self.S
                
                # this epsilon is important to give some of the nodes 
                # some chance to cooperate
                ef[r_index1] = 1 - eps + eps * f[r_index1]
                total_efit += ef[r_index1]
                
                # keep the degrees updates for PA
                degrees[r_index1] = len_adj
                total_degrees += degrees[r_index1]
                
                       
        # set the class attribute
        self.total_fit = total_fit
        self.total_efit = total_efit
        self.total_degrees = total_degrees
        
        # population will  collapse
        if self.size - len(to_remove) < self.e_per_gen:
            print ("population collapsed with", 
                   count_coop(sn), "cooperators and",
                   self.size - count_coop(sn), "defectors" )

        # remove nodes that didn't have any edges            
        for n in to_remove:
            r_index = g.node[n]['r_index']
            self.fitness_of[r_index] = -1
            self.free_indexes.append(r_index)
            self.node_set.discard(n)
            g.remove_node(n)
            self.size -= 1

        
    def update_strategies(self):
        g = self.g
        self.gen += 1
        cooperators = 0
        degrees = self.degrees
        
        for n1 in g.nodes_iter(data = True):
            
            neighbors_n1 = g.neighbors(n1[0])
            r_index1 = n1[1]['r_index']
                        
            n2_index = random.choice(neighbors_n1)
            n2 = g.node[n2_index]
            
            # check that the strategies are actually different
            if n1[1]['st'] != n2['st']:
                
                r_n1 = self.fitness[r_index1]
                r_n2 = self.fitness[n2['r_index']]
                
                # Look to see if difference is less than a millionth of
                # largest value and then assume equivalence
                epsilon_fitness = max(r_n2,r_n1) / 1000000
                
                # if the neighbor has a bigger accumulated fitness
                if r_n2 > r_n1 + epsilon_fitness:
                    
                    #   probP = (neighbour_fitness - focal_node_fitness)
                    #           ----------------------------------------
                    #               b * max[k_focal_node, k_neighbour]
                    
                    if random.random() < \
                            (1.0 * (r_n2 - r_n1)) / \
                            (self.b * max(len(neighbors_n1), \
                            len(g.neighbors(n2_index)))):
                        # update the strategy to a temporary vector
                        n1[1]['nst'] = n2['st']

                    
                    """
                    Poncela´s Formula gives to much weight to the number 
                    of nodes, this is an alternate version that would be
                    worth to test:
                      
                    probability P = neighbour_fitness   focal_node_fitness
                                    ------------------ - -----------------
                                     b * k_neighbour      b * k_focal_node

                    
                    if random.random() < (1.0 * r_n2) / \
                                         (self.b*len(g.neighbors(n2_index)))-\
                                         (1.0 * r_n1) / \
                                         (self.b*len(neighbors_n1)):
                     n1[1]['nst'] = n2['st']
                     """
            
            # update cooperators counter
            if n1[1]['nst'] == COOP:
                cooperators += 1
                
        self.cooperators = cooperators
    
    
    def growth_initial(self, growth):
        """ This method make sure that the first growth completes the nodes
        necessary to get to a consistent increment of 10 per generation. It
        just applies for starting networks that are smaller than self.n_per_gen 
        """
        if self.size < self.n_per_gen:
            temp = self.n_per_gen
            self.n_per_gen = self.n_per_gen - self.count
            growth(self)
            self.n_per_gen = temp



    def attrition(self, selection_method):
        g = self.g

        # it should be call losers
        winners = selection_method(self)
      
        # remove the winning nodes
        for winner in winners:    
            # remove the node from the graph and update fitness arrays
            r_index = g.node[winner]['r_index']
            self.fitness_of[r_index] = -1
            self.free_indexes.append(r_index)
            self.node_set.discard(winner)
            g.remove_node(winner)
            self.size -= 1
            
        # I have moved the removal of nodes with no edges to the play_games 
        # phase to save optimize the code. The auxiliary method remove_isolated
        # has been created in order to produce real results.
        
    def remove_isolated(self, select_winners):
        g = self.g
        to_remove = []

        for n, adj in g.adj.items():
            if (len(adj) == 0):
                to_remove.append(n)
                self.removed_nodes += 1
        
        if self.size - len(to_remove) < self.e_per_gen:
            print ("population collapsed with", 
                   self.count_coop(), "cooperators and",
                   self.size - self.count_coop(), "defectors" )
            
        for n in to_remove:
            r_index = g.node[n]['r_index']
            self.fitness_of[r_index] = -1
            self.free_indexes.append(r_index)
            self.node_set.discard(n)
            g.remove_node(n)
            self.size -= 1
コード例 #30
0
def generate_workload(input_swf,
                      output_json,
                      computation_speed,
                      job_walltime_factor=2,
                      given_walltime_only=False,
                      job_grain=1,
                      platform_size=None,
                      indent=None,
                      translate_submit_times=False,
                      keep_only=False,
                      verbose=False,
                      quiet=False,
                      job_size_function_string='1*nb_res'):
    """Generate a Batsim workload from a SWF trace."""
    element = '([-+]?\d+(?:\.\d+)?)'
    r = re.compile('\s*' + (element + '\s+') * 17 + element + '\s*')

    current_id = 0
    version = 0

    # Let a job be a tuple (job_id, nb_res, run_time, submit_time, profile,
    # walltime)

    jobs = []
    profiles = SortedSet()

    nb_jobs_discarded = 0
    minimum_observed_submit_time = float('inf')

    # Let's loop over the lines of the input file
    for line in input_swf:
        res = r.match(line)

        if res:
            job_id = (int(float(res.group(SwfField.JOB_ID.value))))
            nb_res = int(
                float(res.group(SwfField.ALLOCATED_PROCESSOR_COUNT.value)))
            run_time = float(res.group(SwfField.RUN_TIME.value))
            submit_time = max(0, float(res.group(SwfField.SUBMIT_TIME.value)))
            walltime = max(job_walltime_factor * run_time,
                           float(res.group(SwfField.REQUESTED_TIME.value)))

            # nb_res may be changed by calling a user-given function
            nb_res = eval(job_size_function_string)

            if given_walltime_only:
                walltime = float(res.group(SwfField.REQUESTED_TIME.value))

            if nb_res > 0 and walltime > run_time and run_time > 0 and submit_time >= 0:
                profile = int(((run_time // job_grain) + 1) * job_grain)
                profiles.add(profile)

                job = (current_id, nb_res, run_time, submit_time, profile,
                       walltime)
                current_id = current_id + 1
                minimum_observed_submit_time = min(
                    minimum_observed_submit_time, submit_time)
                jobs.append(job)
            else:
                nb_jobs_discarded += 1
                if verbose:
                    print('Job {} has been discarded'.format(job_id))

    # Export JSON
    # Let's generate a list of dictionaries for the jobs
    djobs = list()
    for (job_id, nb_res, run_time, submit_time, profile, walltime) in jobs:
        use_job = True
        if keep_only is not None:
            use_job = eval(keep_only)

        if use_job:
            djobs.append({
                'id': job_id,
                'subtime': submit_time - minimum_observed_submit_time,
                'walltime': walltime,
                'res': nb_res,
                'profile': str(profile)
            })

    # Let's generate a dict of dictionaries for the profiles
    dprofs = {}
    for profile in profiles:
        dprofs[str(profile)] = {
            'type': 'msg_par_hg',
            'cpu': profile * computation_speed,
            'com': 0.0
        }

    biggest_job = max([
        nb_res
        for (job_id, nb_res, run_time, submit_time, profile, walltime) in jobs
    ])

    if platform_size is not None:
        if platform_size < 1:
            raise Exception(
                'Invalid input: platform size must be strictly positive')
        if platform_size < biggest_job:
            print('Warning: platform size {size} is smaller than '
                  'the biggest job ({big})'.format(size=platform_size,
                                                   big=biggest_job))
    else:
        platform_size = biggest_job

    data = {
        'version': version,
        'command': ' '.join(sys.argv[:]),
        'date': datetime.datetime.now().isoformat(' '),
        'description': 'this workload had been automatically generated',
        'nb_res': platform_size,
        'jobs': djobs,
        'profiles': dprofs
    }

    try:
        outFile = open(output_json, 'w')

        json.dump(data, outFile, indent=indent, sort_keys=True)

        if not quiet:
            print('{} jobs and {} profiles had been created'.format(
                len(djobs), len(dprofs)))
            print('{} jobs have been discarded'.format(nb_jobs_discarded))
            if keep_only:
                print('{} jobs have been removed by keep_only'.format(
                    len(jobs) - len(djobs)))

    except IOError:
        print('Cannot write file', output_json)
コード例 #31
0
    def execute(self):
        self.controller.signal_algo_start()
        dist = []
        vis = []
        INF = 9999
        for i in range(self.DS.n):
            dist.append(INF)
            vis.append(0)
        dist[self.DS.start] = 0
        ss = SortedSet()
        ss.add((0, self.DS.start))
        finish = []
        while len(ss) > 0:
            (cost, nod) = ss.pop(0)
            if vis[nod] == 1:
                continue
            vis[nod] = 1
            finish.append(nod)
            self.controller.wait_for_next_step()
            file = open(self.DS.filename, "w")
            file.write(
                str(self.DS.n) + " " + str(self.DS.m) + " " + str(self.DS.tp) +
                '\n')
            self.DS.nodes[nod]['color'] = (255, 0, 0)
            file.write(str(self.DS.nodes) + '\n')
            file.write(str(self.DS.edges) + '\n')
            file.close()
            self.controller.signal_step_done()
            update = []
            if nod in self.DS.graph.keys():
                for nxt in self.DS.graph[nod]:
                    if vis[nxt[0]] == 0 and dist[nxt[0]] > dist[nod] + nxt[1]:
                        update.append(nxt[0])
                        dist[nxt[0]] = dist[nod] + nxt[1]
                        ss.add((dist[nxt[0]], nxt[0]))

            self.controller.wait_for_next_step()
            file = open("test.txt", "w")
            file.write(str(self.DS.n) + "\n")
            for k in range(self.DS.n):
                if k in finish:
                    file.write("{'content':" + str(dist[k]) +
                               ", 'color':(255,0,0)}\n")
                elif k in update:
                    file.write("{'content':" + str(dist[k]) +
                               ", 'color':(0,255,100)}\n")
                else:
                    file.write("{'content':" + str(dist[k]) +
                               ", 'color':(100,100,100)}\n")
            file.close()
            self.controller.signal_step_done()

        self.controller.wait_for_next_step()
        for i in range(self.DS.n):
            self.DS.nodes[i]['color'] = (112, 112, 112)
        file = open(self.DS.filename, "w")
        file.write(
            str(self.DS.n) + " " + str(self.DS.m) + " " + str(self.DS.tp) +
            '\n')
        file.write(str(self.DS.nodes) + '\n')
        file.write(str(self.DS.edges) + '\n')
        file.close()
        self.controller.signal_step_done()

        self.controller.wait_for_next_step()
        file = open("test.txt", "w")
        file.write(str(self.DS.n) + "\n")
        for k in range(self.DS.n):
            file.write("{'content':" + str(dist[k]) +
                       ", 'color':(100,100,100)}\n")
        file.close()
        self.controller.signal_step_done()
        self.controller.signal_algo_done()
コード例 #32
0
    def _merge_slot_iteration(
        self,
        slot_values: "SlotValues",
        previously_updated: Iterable[TemplateSlot],
        slot_list: List[TemplateSlot],
        slot_indices: Dict[TemplateSlot, int],
        relative_similarity_threshold: float,
    ):
        updated = SortedSet()
        length = len(slot_values.keys())

        # Go over all slots
        # TODO: make it only go over updated
        # for i_key in previously_updated:
        #     i = slot_indices[i_key]
        for i in range(len(slot_list)):
            i_key = slot_list[i]
            i_changed = False

            # If this slot is not already getting replaced
            if i_key not in slot_values.get_replacements().keys():
                i_vals = set(slot_values[i_key])

                # Check for all other slots that are ordinally later
                for j in range(i + 1, length):
                    j_key = slot_list[j]
                    j_vals = slot_values[j_key]

                    ij_changed, i_vals = _absorb_slot_if_similar(
                        i_key,
                        i_vals,
                        j_key,
                        j_vals,
                        slot_values,
                        relative_similarity_threshold,
                    )

                    if ij_changed and j_key not in updated:
                        updated.add(j_key)

                    i_changed = i_changed or ij_changed

                # Check if i values contain the j slot on itself (thus being a superset of j)
                i_changed, i_vals = _remove_values_if_containg_slot_already_maps(
                    i_changed, i, i_vals, slot_indices, slot_values)

                # Check if some slots it refers to are contained by the content of all other slots
                i_changed, i_vals = _remove_unnecessary_slot_references(
                    i_changed, i_vals, slot_values)

                # Check if i has replacable slots: rename these template slots to the new ones
                i_changed, i_vals = _replace_all_replacable_slots(
                    i_changed, i_vals, slot_values)

                # Check if i contains itself
                i_changed, i_vals = _filter_out_self(i_changed, i_key, i_vals)

                # Check if i only contains a single value
                if len(i_vals) == 1:
                    single = next(iter(i_vals))
                    # Check if the value it maps to is a pure slot, and if so, mark as replaced
                    if (len(single.get_elements()) == 1
                            and single.get_elements()[0].is_slot()):
                        slot_values.add_replacement(i_key,
                                                    single.get_elements()[0])
                        i_changed = True
                    # Otherwise, just replace all occurrences of this slot with the new values
                    else:
                        pass  # TODO: add slot removal
                        # new_slot_values.

                # Store all newly found i_vals
                slot_values[i_key] = i_vals

            # Replacement exists
            else:
                # Update replacement to purest replacement
                i_changed = i_changed or _update_to_most_specific_replacement(
                    i_key, slot_values)
            if i_changed and i_key not in updated:
                updated.add(i_key)

        return updated
コード例 #33
0
ファイル: plotTimeError.py プロジェクト: willis-hu/spyn
def plotBoxes(data,
              col,
              ylabel,
              minticks,
              fname,
              plotXLabels=False,
              plotLegend=False,
              figsize=(6, 3.6)):
    fig = figure(figsize=figsize)
    ax = axes()
    hold(True)

    maxval = 0

    batch = 0
    alldims = natsorted(data.keys(), alg=ns.IGNORECASE)
    labels = SortedSet()
    for dims in alldims:
        print(dims)
        expsdata = data[dims]
        bpdata = numpy.zeros((50, 0))
        for method in natsorted(expsdata.keys(), alg=ns.IGNORECASE):
            labels.add(method)
            mdata = expsdata[method]
            print(method)
            networkerror = numpy.asarray(mdata)[:, col].reshape(50, 1)
            if numpy.max(networkerror) > maxval:
                maxval = numpy.max(networkerror)
            bpdata = numpy.append(bpdata, networkerror, axis=1)
        #bpdata = numpy.log(bpdata)
        # print(bpdata)
        positions = numpy.asarray([1, 2, 3, 4]) + (5 * batch)
        box = boxplot(bpdata + 1, positions=positions, widths=0.85)
        batch += 1

        colors = ['b', 'g', 'k', 'r']
        for elem in ['boxes', 'caps', 'whiskers', 'medians']:
            elems = len(box[elem])
            i = 1
            if elems > 4:
                i = 2
            for e in range(elems):
                setp(box[elem][e], linewidth=3)
                setp(box[elem][e], color=colors[floor(e / i)])

    plt.ylabel(ylabel, fontsize=18)
    if plotXLabels:
        ax.set_xticklabels(map(
            lambda dim: "n=" + dim.split("_")[0] + "\nd=" + dim.split("_")[1],
            alldims),
                           multialignment='left',
                           fontsize=16)
        ax.set_xticks(numpy.asarray([2.5, 7.5, 12.5, 17.5, 22.5]))
    else:
        ax.xaxis.set_major_formatter(NullFormatter())

    xlim(0, batch * 5)
    #ylim(-maxval * 0.1, maxval * 1.1)

    for b in range(batch):
        ax.axvline(x=5 * b, c="k", linewidth=0.5, zorder=0)

    ax.set_yscale("log")
    #ylim(-10000.0,10.0)

    #ax.set_yticks(numpy.arange(maxval, maxval*0.1)*2, minor=True)
    #ax.set_yticks(numpy.arange(0, maxval*1.1, minticks), minor=True)
    ax.yaxis.grid(True, which='major', linestyle='--', color='k')
    ax.yaxis.grid(True, which='minor', linestyle='--', color='#DBDBDB')
    [line.set_zorder(3) for line in ax.lines]

    if plotLegend:
        leg = legend(list(
            map(
                lambda l: l.replace("_", " ").upper().replace("XMRF", "LPGM").
                replace("GLMPTEST ", "PSPN p="), labels)),
                     bbox_to_anchor=(0.54, 1.02))
        ax.add_artist(leg)
        ltext = leg.get_texts()
        setp(ltext[0], fontsize=14, color='b')
        setp(ltext[1], fontsize=14, color='g')
        setp(ltext[2], fontsize=14, color='k')
        setp(ltext[3], fontsize=14, color='r')
        for line, txt in zip(leg.get_lines(), leg.get_texts()):
            line.set_linewidth(10)
            line.set_color(txt.get_color())
        for lh in leg.legendHandles:
            lh.set_dashes((None, None))

    [tick.label.set_fontsize(16) for tick in ax.yaxis.get_major_ticks()]

    savefig(fname, bbox_inches='tight', dpi=600)
コード例 #34
0
    def oddEvenJumps(self, arr: List[int]) -> int:
        # Time Complexity: O(N log N)
        # Space Complexity: O(N)

        nearest_larger = []
        nearest_smaller = []

        sorted_set = SortedSet()
        for i in range(len(arr) - 1, -1, -1):
            val = arr[i]

            if sorted_set:
                ind = sorted_set.bisect_left((val, -i))

                if ind == 0:
                    nearest_smaller.append(len(arr))
                else:
                    nearest_smaller.append(-sorted_set[ind - 1][1])
            else:
                nearest_smaller.append(len(arr))

            sorted_set.add((val, -i))

        nearest_smaller = nearest_smaller[::-1]

        sorted_set = SortedSet()
        for i in range(len(arr) - 1, -1, -1):
            val = arr[i]

            if sorted_set:
                ind = sorted_set.bisect_left((-val, -i))

                if ind == 0:
                    nearest_larger.append(len(arr))
                else:
                    nearest_larger.append(-sorted_set[ind - 1][1])
            else:
                nearest_larger.append(len(arr))

            sorted_set.add((-val, -i))

        nearest_larger = nearest_larger[::-1]

        dp = {}

        def reachable(index: int, is_even: bool):
            if (index, is_even) in dp:
                return dp[(index, is_even)]

            if index == len(arr) - 1:
                return True

            next_arr = nearest_smaller if is_even else nearest_larger
            ret = next_arr[index] < len(arr) and reachable(
                next_arr[index], not is_even)

            dp[(index, is_even)] = ret
            return ret

        ret = 0
        for i in range(len(arr)):
            ret += int(reachable(i, False))

        return ret
コード例 #35
0
 def __get_column_info(self, table: str) -> SortedSet:
     columns = SortedSet()
     for row in self.engine.execute("PRAGMA table_info(%s)" % table):
         columns.add(row["name"])
     return columns
コード例 #36
0
class EventManager:
    def __init__(self, resource_manager, dispatcher, additional_data,
                 **kwargs):
        """

        This class coordinates events submission, queueing and ending.

        :param resource_manager: Resource manager instance
        :param \*\*kwargs: nothing for the moment.

        """
        assert (isinstance(
            resource_manager,
            ResourceManager)), 'Wrong type for the resource_manager argument.'
        self.resource_manager = resource_manager
        self.dispatcher = dispatcher
        self.additional_data = additional_data
        self.constants = CONSTANT()
        # self.debug = debug
        # Stats
        self.first_time_dispatch = None
        self.last_run_time = None
        self.slowdowns = []
        self.wtimes = []

        self.current_time = None
        self.time_points = SortedSet()
        self.events = SortedDict()
        self.loaded = SortedDict()
        self.queued = []
        self.real_ending = SortedDict()
        self.running = []
        self.finished = 0

        self._logger = logging.getLogger('accasim')

        self._writers = []
        if self.constants.SCHEDULING_OUTPUT:
            _sched_fp = path.join(
                self.constants.RESULTS_FOLDER_PATH,
                self.constants.SCHED_PREFIX + self.constants.WORKLOAD_FILENAME)
            self._sched_writer = AsyncWriter(
                path=_sched_fp,
                pre_process_fun=EventManager._schd_write_preprocessor)
            self._writers.append(self._sched_writer)

        if self.constants.PPRINT_OUTPUT:
            _pprint_fp = path.join(
                self.constants.RESULTS_FOLDER_PATH,
                self.constants.PPRINT_PREFIX +
                self.constants.WORKLOAD_FILENAME)
            self._pprint_writer = AsyncWriter(
                path=_pprint_fp,
                pre_process_fun=EventManager._schd_pprint_preprocessor)
            self._writers.append(self._pprint_writer)

        for ad in self.additional_data:
            ad.set_event_manager(self)

    def load_events(self, es):
        """

        Jobs are loaded to the system. This is the first step for a job simulation.

        :param es: List of jobs. Jobs must be subclass of event class.

        """
        for ad in self.additional_data:
            ad.exec_before_submission(es)

        if isinstance(es, list):
            for e in es:
                assert (isinstance(
                    e, Event)), 'Only subclasses of event can be simulated.'
                self.load_event(e)
        else:
            assert (isinstance(
                es, Event)), 'Only subclasses of event can be simulated.'
            self.load_event(es)

        for ad in self.additional_data:
            ad.exec_after_submission()

    def load_event(self, e):
        """

        Internal method for job submission.

        :param e: Single job (event subclass).

        """
        assert (isinstance(e,
                           Event)), 'Using {}, expecting a single {}'.format(
                               e.__class__, Event.__name__)
        if not self.current_time:
            self.current_time = e.queued_time - 1
            self.time_points.add(self.current_time)
        if self.current_time == e.queued_time:
            self.submit_event(e.id)
        elif self.current_time < e.queued_time:
            if e.queued_time not in self.loaded:
                self.loaded[e.queued_time] = []
            self.loaded[e.queued_time].append(e.id)
            self.time_points.add(e.queued_time)
        else:
            raise EventException(
                'Time sync problem, the actual event {} was loaded after ({}) the real submit time ({}). This a programming error, must be checked.'
                .format(e.id, self.current_time, e.queued_time))

    def move_to_finished(self, events_dict):
        """

        There are two time points for a job could ends, the expected one and the real one.
        The job must run until the real one is reached, then if a job is waiting to finish but is less than the
        real ending time, this value must be updated with the real one.

        :param events_dict: Actual Loaded, queued and running jobs in a dictionary {id: job object}

        :return: Array of completed jobs

        """
        _es = []
        for e_id in self.real_ending.pop(self.current_time, []):
            if e_id in self.running:
                self.running.remove(e_id)
                e = events_dict[e_id]
                self.finish_event(e)
                _es.append(e_id)
        if (not self.loaded and not self.running and not self.queued) and _es:
            self.last_run_time = self.current_time
        return _es

    def finish_event(self, e):
        """

        Internal method for Job's completion. This method sets the ending time, and make some standard calculations for statistics, such as slowdown, waiting time.
        Finally it calls the methods for output.

        :param e: Job to be completed.

        """
        e.end_time = self.current_time
        e.running_time = e.end_time - e.start_time
        e.waiting_time = e.start_time - e.queued_time
        e.slowdown = float(
            "{0:.2f}".format(
                (e.waiting_time + e.running_time) / e.running_time)
        ) if e.running_time != 0 else e.waiting_time if e.waiting_time != 0 else 1.0
        self.slowdowns.append(e.slowdown)
        self.wtimes.append(e.waiting_time)
        self.finished += 1
        e.end_order = self.finished
        if self.constants.SCHEDULING_OUTPUT:
            self._sched_writer.push(e)
        if self.constants.PPRINT_OUTPUT:
            self._pprint_writer.push(e)

    def dispatch_event(self, _job, _time, _time_diff, _nodes):
        """

        Internal method for Job's dispatching. This method updates the related attributes for allocation of the job.

        :param _job: Job object
        :param _time: Time of dispatching
        :param _time_diff: Time used if dispatching processing _time must be considered.
        :param _nodes: Nodes to be allocated.

        :return: True if the allocation must be performed, false otherwise. False for jobs that have duration equal to 0

        """
        _id = _job.id
        start_time = _time + _time_diff

        #=======================================================================
        # started, started_ended, postponed
        # state = (0, 0, 0)
        #=======================================================================
        assert (self.current_time == start_time
                ), 'Start _time is different to the current _time'

        # Try to allocate
        done, msg = self.resource_manager.allocate_event(_job, _nodes)
        if not done:
            self._logger.error(
                '{} Must be postponed. Reason: {}. If you see this message many times, probably you have to check your allocation heuristic.'
                .format(_id, msg))
            self.submit_event(_id)
            return (0, 0, 1)

        # Continue with a successfully allocated job
        # Update job info
        _job.start_time = start_time
        _job.assigned_nodes = _nodes

        # Initialize the output writers
        if self.first_time_dispatch == None:
            self.first_time_dispatch = start_time
            for writer in self._writers:
                writer.start()
        ans = (1, 0, 0)
        real_end_time = _job.start_time + _job.duration
        if _job.duration == 0:
            self._logger.trace(
                '{}: {} Dispatched and Finished at the same moment. Job Lenght 0'
                .format(self.current_time, _id))
            ans = (0, 1, 0)
        else:
            # Include real ending time int time points
            self.time_points.add(real_end_time)

        # Move to running jobs
        self.running.append(_id)

        # Relate ending time with job id
        if real_end_time not in self.real_ending:
            self.real_ending[real_end_time] = []
        self.real_ending[real_end_time].append(_id)

        return ans

    def submit_event(self, _id):
        """

        Internal method for Job's queueing.

        """
        self.queued.append(_id)

    def next_events(self):
        """

        Return the jobs that belongs to the next time point.

        :return: Array of jobs recently submitted + queued available at current time.

        """
        if len(self.time_points) > 0:
            self.current_time = self.time_points.pop(0)
        else:
            self._logger.trace(
                'No more time points... but there still jobs in the queue')
            self.current_time += 1
        submitted = self.loaded.pop(self.current_time, [])
        new_queue = self.queued + submitted
        self._logger.trace(
            '{} Next events: \n-Recently submited: {}\n-Already queued: {}'.
            format(self.current_time, submitted, self.queued))
        self.queued.clear()

        return new_queue

    def has_events(self):
        """

        :return: True if are loaded, queued or running jobs. False otherwise.

        """
        return (self.loaded or self.queued or self.running)

    def call_dispatcher(self, event_dict, events):
        """
            Call the defined dispatcher. In addition, before the dispatcher call, the exec_before_dispatching method of 
            AdditionalData objects is called passing the job dictionary and current queue job ids. After the dispatcher call, 
            it calls the exec_after_dispatching and pass the job dictionary, the dispatching tuple and the rejected list.    
            
            :return: Return a tuple with a list of jobs to dispatch and to reject.  
        """
        for ad in self.additional_data:
            ad.exec_before_dispatching(event_dict, events)

        to_dispatch, rejected = self.dispatcher.schedule(
            self.current_time, event_dict, events)

        for ad in self.additional_data:
            _tmp = ad.exec_after_dispatching(event_dict, to_dispatch, rejected)
            if _tmp:
                to_dispatch, rejected = _tmp
        return to_dispatch, rejected

    def dispatch_events(self,
                        event_dict,
                        to_dispatch,
                        time_diff,
                        omit_timediff=True):
        """

        Internal method for processing the job's dispatching. Jobs are started if start time is equals to current time.

        :param event_dict: Actual Loaded, queued and running jobs in a dictionary {id: job object}
        :param to_dispatch: A tuple which contains the (start time, job id, nodes)
        :param time_diff: Time which takes the dispatching processing time.
        :param omit_timediff: If True the time spent in generating a decision is considered as 0. False this time is considered, and all events in \
            in [current time, current time + time diff] are moved to the new current time (current time + time diff). The latter isn't implemented. 

        :return return a tuple of (#dispatched, #Dispatched + Finished (0 duration), #postponed)
        """
        if omit_timediff:
            time_diff = 0

        n_disp = 0
        n_disp_finish = 0
        n_post = 0

        for (_time, _id, _nodes) in to_dispatch:
            assert (
                isinstance(_id, str)
            ), 'Please check your return tuple in your Dispatching method. _id must be a str type. Received wrong type: {}'.format(
                _id.__class__)
            assert (_time is None or
                    _time >= self.current_time), 'Receiving wrong schedules.'

            #===================================================================
            # Time must be equal or later than current time.
            #     Equals will be dispatched in the momement, instead later ones, which will be requeued with expected ending time of the job that release the resources.
            # If the expected ending is surpass, because the job takes more time to finish, the time tuple\'s element must be None. '
            #===================================================================
            if not _nodes:
                # For blocked jobs
                if _time is not None and _time != self.current_time:
                    self.time_points.add(_time)
                #==============================================================
                # Maintaining the event in the queue
                #==============================================================
                self.submit_event(_id)
                n_post += 1
                continue

            #=======================================================================
            # started, started_ended, postponed
            #=======================================================================
            dispatched, ended, postponed = self.dispatch_event(
                event_dict[_id], _time, time_diff, _nodes)
            n_disp += dispatched
            n_disp_finish += ended
            n_post += postponed

        if n_disp_finish > 0:
            self.release_ended_events(event_dict)
        return (n_disp, n_disp_finish, n_post)

    def release_ended_events(self, event_dict):
        """

        Internal method for completed jobs. Removes from the dictionary finished jobs.

        :param event_dict: Actual Loaded, queued and running jobs in a dictionary {id: job object}

        :return: return Array list of jobs objects.

        """
        for ad in self.additional_data:
            ad.exec_before_completion()

        _es = self.move_to_finished(event_dict)

        if _es:
            _removed_jobs = []
            for _e in _es:
                self.resource_manager.remove_event(_e)
                # Freeing mem (finished events)
                _removed_jobs.append(event_dict.pop(_e))

            for ad in self.additional_data:
                ad.exec_after_completion(_removed_jobs)

        return _es

    def simulated_status(self):
        """

        Show the current state of the system in terms of loaded, queued, running and finished jobs.

        :return: String including the system info.

        """
        return (
            'Loaded {}, Queued {}, Running {}, and Finished {} Jobs'.format(
                len(self.loaded), len(self.queued), len(self.running),
                self.finished))

    def availability(self):
        """

        Current availability of the system.

        :return: Return the availability of the system.

        """
        return self.resource_manager.current_availability

    def usage(self):
        """

        Current usage of the system

        :return: Return the usage of the system

        """
        return self.resource_manager.current_usage

    def simulated_current_time(self):
        """

        Current time

        :return: Return the current simulated time

        """
        return self.current_time

    def stop_writers(self):
        """
        Stops the output writer threads and closes the file streams
        """
        for i in range(len(self._writers)):
            self._writers[i].stop()
            self._writers[i] = None

        for ad in self.additional_data:
            ad.stop()

    @staticmethod
    def _schd_write_preprocessor(event):
        """
        To be used as a pre-processor for AsyncWriter objects applied to event schedules.
        Pre-processes an event object and converts it to a String representation.
        It uses the format specified in the SCHEDULE_OUTPUT constant.

        :param event: The event to be written to output
        """
        constants = CONSTANT()
        _dict = constants.SCHEDULE_OUTPUT
        _attrs = {}
        for a, av in _dict['attributes'].items():
            try:
                _attrs[a] = locate(av[-1])(*event.subattr(event, av[:-1]))
            except ValueError:
                _attrs[a] = 'NA'
        output_format = _dict['format']
        return output_format.format(**_attrs) + '\n'

    @staticmethod
    def _schd_pprint_preprocessor(event):
        """
        To be used as a pre-processor for AsyncWriter objects applied to pretty-print event schedules.
        Pre-processes an event object and converts it to a String representation.
        It uses the format specified in the PPRINT_SCHEDULE_OUTPUT constant.

        :param event: The event to be written to output
        """
        constants = CONSTANT()
        _dict = constants.PPRINT_SCHEDULE_OUTPUT
        _order = _dict['order']
        _attrs = {}
        for a, av in _dict['attributes'].items():
            try:
                _attrs[a] = locate(av[-1])(*event.subattr(event, av[:-1]))
            except ValueError:
                _attrs[a] = 'NA'
        output_format = _dict['format']
        values = [_attrs[k] for k in _order]
        if event.end_order == 1:
            return (output_format.format(*_order) + '\n',
                    output_format.format(*values) + '\n')
        else:
            return output_format.format(*values) + '\n'

    def __str__(self):
        """

        Str representation of the event job_mapper
        
        :return: Return the current system info.

        """
        return 'Loaded: {}\nQueued: {}\nRunning: {}\nReal job finish on: {},\nFinished: {}\nNext time events: {}'.format(
            self.loaded, self.queued, self.running, self.real_ending,
            self.finished, self.time_points)
コード例 #37
0
class PlatformBatchLightSystem:
    """Batch light system for platforms."""

    __slots__ = [
        "dirty_lights", "dirty_schedule", "clock", "update_task",
        "update_callback", "update_hz", "max_batch_size", "scheduler_task",
        "schedule_changed", "dirty_lights_changed"
    ]

    # pylint: disable-msg=too-many-arguments
    def __init__(self, clock, update_callback, update_hz, max_batch_size):
        """Initialise light system."""
        self.dirty_lights = SortedSet()  # type: Set[PlatformBatchLight]
        self.dirty_lights_changed = asyncio.Event(loop=clock.loop)
        self.dirty_schedule = SortedList()
        self.schedule_changed = asyncio.Event(loop=clock.loop)
        self.update_task = None
        self.scheduler_task = None
        self.clock = clock
        self.update_callback = update_callback
        self.update_hz = update_hz
        self.max_batch_size = max_batch_size

    def start(self):
        """Start light system."""
        self.update_task = self.clock.loop.create_task(self._send_updates())
        self.update_task.add_done_callback(Util.raise_exceptions)
        self.scheduler_task = self.clock.loop.create_task(
            self._schedule_updates())
        self.scheduler_task.add_done_callback(Util.raise_exceptions)

    def stop(self):
        """Stop light system."""
        if self.scheduler_task:
            self.scheduler_task.cancel()
            self.scheduler_task = None
        if self.update_task:
            self.update_task.cancel()
            self.update_task = None

    async def _schedule_updates(self):
        while True:
            run_time = self.clock.get_time()
            self.schedule_changed.clear()
            while self.dirty_schedule and self.dirty_schedule[0][0] <= run_time:
                self.dirty_lights.add(self.dirty_schedule[0][1])
                del self.dirty_schedule[0]
            self.dirty_lights_changed.set()

            if self.dirty_schedule:
                await asyncio.wait([self.schedule_changed.wait()],
                                   loop=self.clock.loop,
                                   timeout=self.dirty_schedule[0][0] -
                                   run_time,
                                   return_when=asyncio.FIRST_COMPLETED)
            else:
                await self.schedule_changed.wait()

    async def _send_updates(self):
        poll_sleep_time = 1 / self.update_hz
        max_fade_tolerance = int(poll_sleep_time * 1000)
        while True:
            await self.dirty_lights_changed.wait()
            self.dirty_lights_changed.clear()
            sequential_lights = []
            for light in list(self.dirty_lights):
                if not sequential_lights:
                    # first light
                    sequential_lights = [light]
                elif light.is_successor_of(sequential_lights[-1]):
                    # lights are sequential
                    sequential_lights.append(light)
                else:
                    # sequence ended
                    await self._send_update_batch(sequential_lights,
                                                  max_fade_tolerance)
                    # this light is a new sequence
                    sequential_lights = [light]

            if sequential_lights:
                await self._send_update_batch(sequential_lights,
                                              max_fade_tolerance)

            self.dirty_lights.clear()

            await asyncio.sleep(poll_sleep_time, loop=self.clock.loop)

    async def _send_update_batch(self,
                                 sequential_lights: List[PlatformBatchLight],
                                 max_fade_tolerance):
        sequential_brightness_list = [
        ]  # type: List[Tuple[LightPlatformInterface, float, int]]
        common_fade_ms = None
        current_time = self.clock.get_time()
        for light in sequential_lights:
            brightness, fade_ms, done = light.get_fade_and_brightness(
                current_time)
            if not done:
                schedule_time = current_time + (fade_ms / 1000)
                if not self.dirty_schedule or self.dirty_schedule[0][
                        0] > schedule_time:
                    self.schedule_changed.set()
                self.dirty_schedule.add((schedule_time, light))
            if common_fade_ms is None:
                common_fade_ms = fade_ms

            if -max_fade_tolerance < common_fade_ms - fade_ms < max_fade_tolerance and \
                    len(sequential_brightness_list) < self.max_batch_size:
                sequential_brightness_list.append(
                    (light, brightness, common_fade_ms))
            else:
                await self.update_callback(sequential_brightness_list)
                # start new list
                current_time = self.clock.get_time()
                common_fade_ms = fade_ms
                sequential_brightness_list = [(light, brightness,
                                               common_fade_ms)]

        if sequential_brightness_list:
            await self.update_callback(sequential_brightness_list)

    def mark_dirty(self, light: "PlatformBatchLight"):
        """Mark as dirty."""
        self.dirty_lights.add(light)
        self.dirty_lights_changed.set()
        self.dirty_schedule = SortedList(
            [x for x in self.dirty_schedule if x[1] != light])
コード例 #38
0
ファイル: Agenda.py プロジェクト: vishalbelsare/multivac
class Agenda(object):
    def __init__(self, parse):
        self._parse = parse
        self._skipMC = False
        self._skipCompose = False
        self._mc_neighs = dict()
        self._compose_cnt = dict()
        self._agendaToScore = set()
        self._clustIdx_agenda = dict()
        self._inactiveAgenda_score = dict()
        self._activeAgenda_score = dict()
        self._scoreActiveAgenda = SortedSet()  # (float, SearchOp)
        self._minAbsCntObserved =  ParseParams.minAbsCnt \
                                 * (ParseParams.minAbsCnt-1)/2
        # self.logc = open("/Users/ben_ryan/Documents/DARPA ASKE/usp-code/genia_full/create_agenda.log", "a+")
        # self.logp = open("/Users/ben_ryan/Documents/DARPA ASKE/usp-code/genia_full/proc_agenda.log", "a+")

    def save_agenda(self, path):
        '''
            Save all objects necessary to recreate the current state of Agenda
        '''
        with open(path, 'wb') as f:
            pickle.dump({'saved_agenda': self}, f)

        return None

    def load_agenda(path, prs):
        '''
            Given a Parse object, load the saved state of an Agenda and
            attach it, returning the updated Parse object.
        '''
        with open(path, 'rb') as f:
            sav = pickle.load(f)

        prs.agenda = sav['saved_agenda']
        prs.agenda._parse = prs

        return prs

    def createAgenda(self, verbose=False):
        if verbose:
            clust_cnt = len(Part.getClustPartRootNodeIds())
            milestones = set([x for x in range(1, 10, 1)])
            i = 0

        for clust_id in Part.getClustPartRootNodeIds():
            clust = Clust.getClust(clust_id)

            if clust.getType() != 'C':
                continue
            elif clust.isStop():
                continue

            # # self.logc.write("Adding to agenda for cluster {}\n".format(clust_id))
            self.addAgendaForNewClust(clust_id, verbose)

            if verbose:
                i += 1
                done = math.floor(i * 10 / clust_cnt)

                if done in milestones:
                    milestones.remove(done)
                    print("{}% complete.".format(done * 10))

        # self.logc.close()

        return None

    def addAgendaForNewClust(self, newClustIdx, verbose=False):
        part_node_ids = Part.getClustPartRootNodeIds()[newClustIdx]
        num_parts = len(part_node_ids)

        # if verbose:
        #     print("Updating agenda: {} possible operations.".format(num_parts*(num_parts-1)))

        if len(part_node_ids) > 1:
            for node_id in part_node_ids:
                part_1 = Part.getPartByRootNodeId(node_id)

                for node_id2 in part_node_ids:
                    if node_id <= node_id2:
                        break
                    part_2 = Part.getPartByRootNodeId(node_id2)

                    # self.logc.write("\tAdding parts {} and {} to agenda for cluster {}\n".format(node_id, node_id2, newClustIdx))
                    self.addAgendaAfterMergeClust(part_1, part_2)

        return None

    def addAgendaAfterMergeClust(self, part_1, part_2):
        # First, check that these parts belong to the same cluster
        assert part_1._clustIdx == part_2._clustIdx

        clustIdx = part_1._clustIdx

        # If they have parents, check whether the parents are in the same cluster
        # If not, look at merging their clusters, and if so, look at composing
        # the clusters for part_1 and its parent.

        if part_1.getParPart() is not None and part_2.getParPart() is not None:
            clustIdx1 = part_1.getParPart()._clustIdx
            clustIdx2 = part_2.getParPart()._clustIdx

            if clustIdx1 != clustIdx2:
                self.addAgendaMC(clustIdx1, clustIdx2, 2 * clustIdx + 1)
            else:
                self.addAgendaAbs(clustIdx1, clustIdx)

        # Next, get the arguments (children) of each part
        # Compare each argument in A) with each argument in B) - if they have
        # different clusters, look at merging them, and if they have the same
        # look at composing the clusters for part_1 and its argument(s).

        kids_1 = part_1.getArguments()
        kids_2 = part_2.getArguments()
        # # self.logc.write("\tAdding to agenda for kids of {} and {} in {}\n".format(part_1.getRelTreeRoot().getId(),
        #                                                                           part_2.getRelTreeRoot().getId(),
        #                                                                           clustIdx))

        for kid1 in kids_1.values():
            clustIdx1 = kid1._argPart._clustIdx

            for kid2 in kids_2.values():
                clustIdx2 = kid2._argPart._clustIdx

                if clustIdx1 != clustIdx2:
                    #print("Add agenda - Merge Clusters {} and {}".format(clustIdx1, clustIdx2))
                    self.addAgendaMC(clustIdx1, clustIdx2, 2 * clustIdx + 1)
                else:
                    #print("Add agenda - Compose Clusters {} and {}".format(clustIdx, clustIdx1))
                    self.addAgendaAbs(clustIdx, clustIdx1)

        return None

    def addAgendaMC(self, clustIdx1, clustIdx2, neighType):
        if not (self._skipMC or clustIdx1 == clustIdx2):
            type1 = Clust.getClust(clustIdx1).getType()
            type2 = Clust.getClust(clustIdx2).getType()

            if type2 == 'C' and type1 == 'C':
                op = SearchOp()
                op._op = SearchOp.OP_MERGE_CLUST
                op._clustIdx1 = min((clustIdx1, clustIdx2))
                op._clustIdx2 = max((clustIdx1, clustIdx2))

                if not self.moveAgendaToScore(op):
                    if op not in self._mc_neighs:
                        self._mc_neighs[op] = set()

                    if len(self._mc_neighs[op]) + 1 >= ParseParams.minMCCnt:
                        self._agendaToScore.add(op)
                        del self._mc_neighs[op]
                    else:
                        self._mc_neighs[op].add(neighType)

                    ## self.logc.write("\t\tMerge Op: {}; mc_neighs: {}, agendaToScore: {}\n".format(op, len(self._mc_neighs), len(self._agendaToScore)))

        return None

    def addAgendaAbs(self, parClustIdx, chdClustIdx):
        if not self._skipCompose:
            op = SearchOp()
            op._op = SearchOp.OP_COMPOSE
            op._parClustIdx = parClustIdx
            op._chdClustIdx = chdClustIdx

            if not self.moveAgendaToScore(op):
                if op not in self._compose_cnt:
                    self._compose_cnt[op] = 1

                if self._compose_cnt[op] + 1 >= self._minAbsCntObserved:
                    self._agendaToScore.add(op)
                    del self._compose_cnt[op]
                else:
                    self._compose_cnt[op] += 1

                ## self.logc.write("\t\tCompose Op: {}; compose_cnt: {}, agendaToScore: {}\n".format(op, len(self._compose_cnt), len(self._agendaToScore)))

        return None

    def moveAgendaToScore(self, op):
        #assert op in self._activeAgenda_score or op in self._inactiveAgenda_score

        if op in self._agendaToScore:
            return True

        if op in self._activeAgenda_score:
            score = self._activeAgenda_score[op]
            self._scoreActiveAgenda.discard((score, op))
            del self._activeAgenda_score[op]
            self._agendaToScore.add(op)

            return True
        elif op in self._inactiveAgenda_score:
            del self._inactiveAgenda_score[op]
            self._agendaToScore.add(op)

            return True

        return False

    def procAgenda(self, verbose=False):
        if verbose:
            print("Processing agenda with {} operations in queue.".format(
                len(self._agendaToScore)))
        ttlAgendaScored, ttlExecMC, ttlExecAbs = (0, 0, 0)
        i = 1

        while True:
            As = 0

            for op in self._agendaToScore:
                score = self._parse.scorer.scoreOp(op)
                if verbose:
                    print("<SCORE> {} score={}".format(op, score))
                As += 1

                if score < -200:
                    continue

                if verbose:
                    print("<Add Agenda> {} score={}".format(op, score))
                self.addAgenda(op, score)

            self._agendaToScore.clear()
            ttlAgendaScored = As + 1

            if len(self._scoreActiveAgenda) == 0:
                break

            score, op = next(reversed(self._scoreActiveAgenda))
            if verbose:
                print("Executing: {}, score={}".format(op, score))
            newClustIdx = self._parse.executor.executeOp(op)
            self.updateAgendaAfterExec(op, newClustIdx, verbose)

            if op._op == SearchOp.OP_COMPOSE:
                ttlExecAbs += 1
            elif op._op == SearchOp.OP_MERGE_CLUST:
                ttlExecMC += 1

            if verbose:
                print("Total op_compose: {}, Total op_merge_clust: {}".format(
                    ttlExecAbs, ttlExecMC))
            i += 1

            if verbose and i % 10 == 0:
                print("{} Processing agenda: {} loops".format(
                    datetime.now(), i))

        return None

    def addAgenda(self, op, score):
        ci1, ci2 = (-1, -1)

        if op._op == SearchOp.OP_MERGE_CLUST:
            ci1 = op._clustIdx1
            ci2 = op._clustIdx2
        elif op._op == SearchOp.OP_COMPOSE:
            ci1 = op._parClustIdx
            ci2 = op._chdClustIdx

        if ci1 not in self._clustIdx_agenda:
            self._clustIdx_agenda[ci1] = set()

        self._clustIdx_agenda[ci1].add(op)

        if ci2 not in self._clustIdx_agenda:
            self._clustIdx_agenda[ci2] = set()

        self._clustIdx_agenda[ci2].add(op)

        if score < ParseParams.priorCutOff:
            self._inactiveAgenda_score[op] = score
        else:
            self._activeAgenda_score[op] = score
            self._scoreActiveAgenda.add((score, op))

        return None

    def updateAgendaAfterExec(self, op, newClustIdx, verbose=False):
        self.removeAgenda(op)

        if newClustIdx >= 0:
            if op._op == SearchOp.OP_MERGE_CLUST:
                self.updateAgendaAfterExecMC(op, newClustIdx, verbose)
            elif op._op == SearchOp.OP_COMPOSE:
                self.updateAgendaAfterExecAbs(op, newClustIdx, verbose=verbose)

        return None

    def addAgendaToScore(self, op):
        self._agendaToScore.add(op)
        return None

    def updateAgendaAfterExecMC(self, op, newClustIdx, verbose=False):
        assert op._op == SearchOp.OP_MERGE_CLUST

        oldClustIdx = op._clustIdx2

        if oldClustIdx == newClustIdx:
            oldClustIdx = op._clustIdx1

        while len(self._clustIdx_agenda[oldClustIdx]) > 0:
            oop = next(iter(self._clustIdx_agenda[oldClustIdx]))
            self.removeAgenda(oop)

            if oop._op == SearchOp.OP_MERGE_CLUST:
                ci1 = oop._clustIdx1
                ci2 = oop._clustIdx2

                if ci1 == oldClustIdx:
                    ci1 = newClustIdx

                if ci2 == oldClustIdx:
                    ci2 = newClustIdx

                if ci1 != ci2:
                    nop = oop
                    nop._clustIdx1 = min((ci1, ci2))
                    nop._clustIdx2 = max((ci1, ci2))
                    nop.genString()
                    self.addAgendaToScore(nop)
            elif oop._op == SearchOp.OP_COMPOSE:
                ci1 = oop._parClustIdx
                ci2 = oop._chdClustIdx

                if ci1 == oldClustIdx:
                    ci1 = newClustIdx

                if ci2 == oldClustIdx:
                    ci2 = newClustIdx

                nop = oop
                nop._parClustIdx = ci1
                nop._chdClustIdx = ci2
                nop.genString()
                self.addAgendaToScore(nop)

        del self._clustIdx_agenda[oldClustIdx]

        num_parts_old = len(Part.getClustPartRootNodeIds()[oldClustIdx])
        num_parts_new = len(Part.getClustPartRootNodeIds()[newClustIdx])

        if verbose:
            print("Updating agenda: {} possible operations.".format(
                num_parts_new * (num_parts_old)))

        for prnid in Part.getClustPartRootNodeIds()[newClustIdx]:
            p = Part.getPartByRootNodeId(prnid)

            for prnid2 in Part.getClustPartRootNodeIds()[oldClustIdx]:
                p2 = Part.getPartByRootNodeId(prnid2)
                self.addAgendaAfterMergeClust(p, p2)

        return None

    def updateAgendaAfterExecAbs(self,
                                 op,
                                 newClustIdx,
                                 oop=None,
                                 verbose=False):
        if op._op == SearchOp.OP_COMPOSE:
            parClustIdx = op._parClustIdx
            chdClustIdx = op._chdClustIdx

            while len(self._clustIdx_agenda[parClustIdx]) > 0:
                oop = next(iter(self._clustIdx_agenda[parClustIdx]))
                self.removeAgenda(oop)
                # oop.genString()
                self.addAgendaToScore(oop)

            while len(self._clustIdx_agenda[chdClustIdx]) > 0:
                oop = next(iter(self._clustIdx_agenda[chdClustIdx]))
                self.removeAgenda(oop)
                # oop.genString()
                self.addAgendaToScore(oop)

            self.addAgendaForNewClust(newClustIdx, verbose)
        # elif oop is not None:
        #     ci1, ci2 = (-1, -1)

        #     if oop._op == SearchOp.OP_MERGE_CLUST:
        #         ci1 = oop._clustIdx1
        #         ci2 = oop._clustIdx2
        #     elif oop._op == SearchOp.OP_COMPOSE:
        #         ci1 = oop._parClustIdx
        #         ci2 = oop._chdClustIdx

        #     if ci1 in (op._parClustIdx, op._chdClustIdx):
        #         ci1 = newClustIdx

        #     if ci2 in (op._parClustIdx, op._chdClustIdx):
        #         ci2 = newClustIdx

        #     if oop._op == SearchOp.OP_MERGE_CLUST:
        #         if ci1 != ci2:
        #             nop = SearchOp()
        #             nop._clustIdx1 = min((ci1, ci2))
        #             nop._clustIdx2 = max((ci1, ci2))
        #             nop._op = oop._op
        #             self.addAgendaToScore(nop)
        #     elif oop._op == SearchOp.OP_COMPOSE:
        #         nop = SearchOp()
        #         nop._parClustIdx = ci1
        #         nop._chdClustIdx = ci2
        #         nop._op = oop._op
        #         self.addAgendaToScore(nop)

        return None

    def removeAgenda(self, op):
        # assert (op in self._activeAgenda_score or op in self._inactiveAgenda_score)

        if op in self._activeAgenda_score:
            score = self._activeAgenda_score[op]
            self._scoreActiveAgenda.discard((score, op))
            del self._activeAgenda_score[op]
        elif op in self._inactiveAgenda_score:
            del self._inactiveAgenda_score[op]

        if op._op == SearchOp.OP_MERGE_CLUST:
            self._clustIdx_agenda[op._clustIdx1].discard(op)
            self._clustIdx_agenda[op._clustIdx2].discard(op)
        elif op._op == SearchOp.OP_COMPOSE:
            self._clustIdx_agenda[op._parClustIdx].discard(op)
            self._clustIdx_agenda[op._chdClustIdx].discard(op)

        return None
コード例 #39
0
class PlatformBatchLightSystem:

    """Batch light system for platforms."""

    __slots__ = ["dirty_lights", "dirty_schedule", "clock", "update_task", "update_callback",
                 "update_hz", "max_batch_size", "scheduler_task", "schedule_changed", "dirty_lights_changed",
                 "last_state"]

    # pylint: disable-msg=too-many-arguments
    def __init__(self, clock, update_callback, update_hz, max_batch_size):
        """Initialise light system."""
        self.dirty_lights = SortedSet()    # type: Set[PlatformBatchLight]
        self.dirty_lights_changed = asyncio.Event()
        self.dirty_schedule = SortedList()
        self.schedule_changed = asyncio.Event()
        self.update_task = None
        self.scheduler_task = None
        self.clock = clock
        self.update_callback = update_callback
        self.update_hz = update_hz
        self.max_batch_size = max_batch_size
        self.last_state = {}

    def start(self):
        """Start light system."""
        self.update_task = self.clock.loop.create_task(self._send_updates())
        self.update_task.add_done_callback(Util.raise_exceptions)
        self.scheduler_task = self.clock.loop.create_task(self._schedule_updates())
        self.scheduler_task.add_done_callback(Util.raise_exceptions)

    def stop(self):
        """Stop light system."""
        if self.scheduler_task:
            self.scheduler_task.cancel()
            self.scheduler_task = None
        if self.update_task:
            self.update_task.cancel()
            self.update_task = None

    async def _schedule_updates(self):
        while True:
            run_time = self.clock.get_time()
            self.schedule_changed.clear()
            while self.dirty_schedule and self.dirty_schedule[0][0] <= run_time:
                self.dirty_lights.add(self.dirty_schedule[0][1])
                del self.dirty_schedule[0]
            self.dirty_lights_changed.set()

            if self.dirty_schedule:
                try:
                    await asyncio.wait_for(self.schedule_changed.wait(), self.dirty_schedule[0][0] - run_time)
                except asyncio.TimeoutError:
                    pass
            else:
                await self.schedule_changed.wait()

    async def _send_updates(self):
        poll_sleep_time = 1 / self.update_hz
        max_fade_tolerance = int(poll_sleep_time * 1000)
        while True:
            await self.dirty_lights_changed.wait()
            self.dirty_lights_changed.clear()
            sequential_lights = []
            for light in list(self.dirty_lights):
                if not sequential_lights:
                    # first light
                    sequential_lights = [light]
                elif light.is_successor_of(sequential_lights[-1]):
                    # lights are sequential
                    sequential_lights.append(light)
                else:
                    # sequence ended
                    await self._send_update_batch(sequential_lights, max_fade_tolerance)
                    # this light is a new sequence
                    sequential_lights = [light]

            if sequential_lights:
                await self._send_update_batch(sequential_lights, max_fade_tolerance)

            self.dirty_lights.clear()

            await asyncio.sleep(poll_sleep_time)

    async def _send_update_batch(self, sequential_lights: List[PlatformBatchLight], max_fade_tolerance):
        sequential_brightness_list = []     # type: List[Tuple[LightPlatformInterface, float, int]]
        common_fade_ms = None
        current_time = self.clock.get_time()
        for light in sequential_lights:
            brightness, fade_ms, done = light.get_fade_and_brightness(current_time)
            schedule_time = current_time + (fade_ms / 1000)
            if not done:
                if not self.dirty_schedule or self.dirty_schedule[0][0] > schedule_time:
                    self.schedule_changed.set()
                self.dirty_schedule.add((schedule_time, light))
            else:
                # check if we realized this brightness earlier
                last_state = self.last_state.get(light, None)
                if last_state and last_state[0] == brightness and last_state[1] < schedule_time and \
                        not sequential_brightness_list:
                    # we already set the light to that color earlier. skip it
                    # we only skip this light if we are in the beginning of the list for now
                    # the reason for that is that we do not want to break fade chains when one color channel
                    # of an RGB light did not change
                    # this could become an option in the future
                    continue

            self.last_state[light] = (brightness, schedule_time)

            if common_fade_ms is None:
                common_fade_ms = fade_ms

            if -max_fade_tolerance < common_fade_ms - fade_ms < max_fade_tolerance and \
                    len(sequential_brightness_list) < self.max_batch_size:
                sequential_brightness_list.append((light, brightness, common_fade_ms))
            else:
                await self.update_callback(sequential_brightness_list)
                # start new list
                current_time = self.clock.get_time()
                common_fade_ms = fade_ms
                sequential_brightness_list = [(light, brightness, common_fade_ms)]

        if sequential_brightness_list:
            await self.update_callback(sequential_brightness_list)

    def mark_dirty(self, light: "PlatformBatchLight"):
        """Mark as dirty."""
        self.dirty_lights.add(light)
        self.dirty_lights_changed.set()
        self.dirty_schedule = SortedList([x for x in self.dirty_schedule if x[1] != light])
コード例 #40
0
ファイル: replay_buffer.py プロジェクト: facebookresearch/svg
class ReplayBuffer(object):
    """Buffer to store environment transitions."""
    def __init__(self, obs_shape, action_shape, capacity, device,
                 normalize_obs):
        self.obs_shape = obs_shape
        self.action_shape = action_shape
        self.capacity = capacity
        self.device = device

        self.pixels = len(obs_shape) > 1
        self.empty_data()

        self.done_idxs = SortedSet()
        self.global_idx = 0
        self.global_last_save = 0

        self.normalize_obs = normalize_obs

        if normalize_obs:
            assert not self.pixels
            self.welford = utils.Welford()

    def __getstate__(self):
        d = copy.copy(self.__dict__)
        del d['obses'], d['next_obses'], d['actions'], d['rewards'], \
          d['not_dones'], d['not_dones_no_max']
        return d

    def __setstate__(self, d):
        self.__dict__ = d

        # Manually need to re-load the transitions with load()
        self.empty_data()

    def empty_data(self):
        obs_dtype = np.float32 if not self.pixels else np.uint8
        obs_shape = self.obs_shape
        action_shape = self.action_shape
        capacity = self.capacity

        self.obses = np.empty((capacity, *obs_shape), dtype=obs_dtype)
        self.next_obses = np.empty((capacity, *obs_shape), dtype=obs_dtype)
        self.actions = np.empty((capacity, *action_shape), dtype=np.float32)
        self.rewards = np.empty((capacity, 1), dtype=np.float32)
        self.not_dones = np.empty((capacity, 1), dtype=np.float32)
        self.not_dones_no_max = np.empty((capacity, 1), dtype=np.float32)

        self.idx = 0
        self.full = False
        self.payload = []
        self.done_idxs = None

    def __len__(self):
        return self.capacity if self.full else self.idx

    def get_obs_stats(self):
        assert not self.pixels
        MIN_STD = 1e-1
        MAX_STD = 10
        mean = self.welford.mean()
        std = self.welford.std()
        std[std < MIN_STD] = MIN_STD
        std[std > MAX_STD] = MAX_STD
        return mean, std

    def add(self, obs, action, reward, next_obs, done, done_no_max):
        # For saving
        self.payload.append((obs.copy(), next_obs.copy(), action.copy(),
                             reward, not done, not done_no_max))

        if self.normalize_obs:
            self.welford.add_data(obs)

        # if self.full and not self.not_dones[self.idx]:
        if done:
            self.done_idxs.add(self.idx)
        elif self.full:
            self.done_idxs.discard(self.idx)

        np.copyto(self.obses[self.idx], obs)
        np.copyto(self.actions[self.idx], action)
        np.copyto(self.rewards[self.idx], reward)
        np.copyto(self.next_obses[self.idx], next_obs)
        np.copyto(self.not_dones[self.idx], not done)
        np.copyto(self.not_dones_no_max[self.idx], not done_no_max)

        self.idx = (self.idx + 1) % self.capacity
        self.global_idx += 1
        self.full = self.full or self.idx == 0

    def sample(self, batch_size):
        idxs = np.random.randint(0,
                                 self.capacity if self.full else self.idx,
                                 size=batch_size)

        obses = self.obses[idxs]
        next_obses = self.next_obses[idxs]

        if self.normalize_obs:
            mu, sigma = self.get_obs_stats()
            obses = (obses - mu) / sigma
            next_obses = (next_obses - mu) / sigma

        obses = torch.as_tensor(obses, device=self.device).float()
        actions = torch.as_tensor(self.actions[idxs], device=self.device)
        rewards = torch.as_tensor(self.rewards[idxs], device=self.device)
        next_obses = torch.as_tensor(next_obses, device=self.device).float()
        not_dones = torch.as_tensor(self.not_dones[idxs], device=self.device)
        not_dones_no_max = torch.as_tensor(self.not_dones_no_max[idxs],
                                           device=self.device)

        return obses, actions, rewards, next_obses, not_dones, not_dones_no_max

    def sample_multistep(self, batch_size, T):
        assert batch_size < self.idx or self.full

        last_idx = self.capacity if self.full else self.idx
        last_idx -= T

        # raw here means the "coalesced" indices that map to valid
        # indicies that are more than T steps away from a done
        done_idxs_sorted = np.array(list(self.done_idxs) + [last_idx])
        n_done = len(done_idxs_sorted)
        done_idxs_raw = done_idxs_sorted - np.arange(1, n_done + 1) * T

        samples_raw = npr.choice(
            last_idx - (T + 1) * n_done,
            size=batch_size,
            replace=True  # for speed
        )
        samples_raw = sorted(samples_raw)
        js = np.searchsorted(done_idxs_raw, samples_raw)
        offsets = done_idxs_raw[js] - samples_raw + T
        start_idxs = done_idxs_sorted[js] - offsets

        obses, actions, rewards = [], [], []

        for t in range(T):
            obses.append(self.obses[start_idxs + t])
            actions.append(self.actions[start_idxs + t])
            rewards.append(self.rewards[start_idxs + t])
            assert np.all(self.not_dones[start_idxs + t])

        obses = np.stack(obses)
        actions = np.stack(actions)
        rewards = np.stack(rewards).squeeze(2)

        if self.normalize_obs:
            mu, sigma = self.get_obs_stats()
            obses = (obses - mu) / sigma

        obses = torch.as_tensor(obses, device=self.device).float()
        actions = torch.as_tensor(actions, device=self.device)
        rewards = torch.as_tensor(rewards, device=self.device)

        return obses, actions, rewards

    def save_data(self, save_dir):
        if self.global_idx == self.global_last_save:
            return
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        path = os.path.join(
            save_dir, f'{self.global_last_save:08d}_{self.global_idx:08d}.pt')

        payload = list(zip(*self.payload))
        payload = [np.vstack(x) for x in payload]
        self.global_last_save = self.global_idx
        torch.save(payload, path)
        self.payload = []

    def load_data(self, save_dir):
        def parse_chunk(chunk):
            start, end = [int(x) for x in chunk.split('.')[0].split('_')]
            return (start, end)

        self.idx = 0

        chunks = os.listdir(save_dir)
        chunks = filter(lambda fname: 'stats' not in fname, chunks)
        chunks = sorted(chunks, key=lambda x: int(x.split('_')[0]))

        self.full = self.global_idx > self.capacity
        global_beginning = self.global_idx - self.capacity if self.full else 0

        for chunk in chunks:
            global_start, global_end = parse_chunk(chunk)
            if global_start >= self.global_idx:
                continue
            start = global_start - global_beginning
            end = global_end - global_beginning
            if end <= 0:
                continue

            path = os.path.join(save_dir, chunk)
            payload = torch.load(path)
            if start < 0:
                payload = [x[-start:] for x in payload]
                start = 0
            assert self.idx == start

            obses = payload[0]
            next_obses = payload[1]

            self.obses[start:end] = obses
            self.next_obses[start:end] = next_obses
            self.actions[start:end] = payload[2]
            self.rewards[start:end] = payload[3]
            self.not_dones[start:end] = payload[4]
            self.not_dones_no_max[start:end] = payload[5]
            self.idx = end

        self.last_save = self.idx

        if self.full:
            assert self.idx == self.capacity
            self.idx = 0

        last_idx = self.capacity if self.full else self.idx
        self.done_idxs = SortedSet(np.where(1. - self.not_dones[:last_idx])[0])
コード例 #41
0
def fetch_us_forenames(url: str,
                       filename: str,
                       freq_csv_filename: str = "",
                       freq_sex_csv_filename: str = "",
                       min_cumfreq_pct: float = 0,
                       max_cumfreq_pct: float = 100,
                       min_name_length: int = 1,
                       show_rejects: bool = False) -> None:
    """
    Fetch US forenames and store them in a file, one per line.

    Args:
        url:
            URL to fetch file from
        filename:
            filename to write to
        freq_csv_filename:
            optional CSV to write "name, frequency" pairs to, one name per line
        freq_sex_csv_filename:
            optional CSV to write "name, gender, frequency" rows to
        min_cumfreq_pct:
            minimum cumulative frequency (%): 0 for no limit, or above 0 to
            exclude common names
        max_cumfreq_pct:
            maximum cumulative frequency (%): 100 for no limit, or below 100 to
            exclude rare names
        min_name_length:
            minimum word length; all words must be at least this long
        show_rejects:
            report rejected words to the Python debug log
    """
    pipeline = (
        gen_name_info_via_min_length(
            gen_sufficiently_frequent_names(
                gen_us_forename_info(
                    gen_lines_from_binary_files(
                        gen_files_from_zipfiles(
                            gen_binary_files_from_urls([url], on_disk=True),
                            # The zip file contains a README and then a
                            # bunch of files named yob<year>.txt (e.g.
                            # yob1997.txt).
                            filespec="*.txt"
                        )
                    )
                ),
                min_cumfreq_pct=min_cumfreq_pct,
                max_cumfreq_pct=max_cumfreq_pct,
                show_rejects=show_rejects
            ),
            min_name_length=min_name_length,
        )
    )
    names = SortedSet()
    freq = {}  # type: Dict[str, float]
    for nameinfo in pipeline:
        name = nameinfo.name
        if name not in names:
            names.add(name)
            freq[name] = nameinfo.freq_p
    write_words_to_file(filename, names)
    if freq_csv_filename:
        log.info(f"Writing to: {freq_csv_filename}")
        with open(freq_csv_filename, "wt") as f:
            csvwriter = csv.writer(f)
            for name in names:
                csvwriter.writerow([name, freq[name]])
        log.info(f"... finished writing to: {freq_csv_filename}")

    if freq_sex_csv_filename:
        pipeline_by_sex = (
            # As above, but by sex
            gen_name_info_via_min_length(
                gen_sufficiently_frequent_names(
                    gen_us_forename_info_by_sex(
                        gen_lines_from_binary_files(
                            gen_files_from_zipfiles(
                                gen_binary_files_from_urls([url], on_disk=True),
                                filespec="*.txt"
                            )
                        )
                    ),
                    min_cumfreq_pct=min_cumfreq_pct,
                    max_cumfreq_pct=max_cumfreq_pct,
                    show_rejects=show_rejects
                ),
                min_name_length=min_name_length,
            )
        )
        name_sex_pairs = SortedSet()
        sexfreq = {}  # type: Dict[Tuple[str, str], float]
        for nameinfo in pipeline_by_sex:  # type: UsForenameInfo
            name = nameinfo.name
            sex = nameinfo.sex
            name_sex = name, sex
            if name_sex not in name_sex_pairs:
                name_sex_pairs.add(name_sex)
                sexfreq[name_sex] = nameinfo.freq_p
        log.info(f"Writing to: {freq_sex_csv_filename}")
        with open(freq_sex_csv_filename, "wt") as f:
            csvwriter = csv.writer(f)
            for name_sex in name_sex_pairs:
                csvwriter.writerow([name_sex[0],
                                    name_sex[1],
                                    sexfreq[name_sex]])
        log.info(f"... finished writing to: {freq_sex_csv_filename}")
コード例 #42
0
def multidim_search_opt_3(xspace,
                          oracle,
                          epsilon=EPS,
                          delta=DELTA,
                          max_step=STEPS,
                          blocking=False,
                          sleep=0.0,
                          logging=True):
    # type: (Rectangle, Oracle, float, float, float, bool, float, bool) -> ResultSet

    # xspace is a particular case of maximal rectangle
    # xspace = [min_corner, max_corner]^n = [0, 1]^n
    # xspace.min_corner = (0,) * n
    # xspace.max_corner = (1,) * n

    # Dimension
    n = xspace.dim()

    # Set of comparable and incomparable rectangles, represented by 'alpha' indices
    comparable = comp(n)
    incomparable = incomp(n)
    # comparable = [zero, one]
    # incomparable = list(set(alpha) - set(comparable))
    # with:
    # zero = (0_1,...,0_n)
    # one = (1_1,...,1_n)

    # List of incomparable rectangles
    # border = [xspace]
    # border = SortedListWithKey(key=Rectangle.volume)
    border = SortedSet([], key=Rectangle.volume)
    border.add(xspace)

    lattice_border_ylow = Lattice(dim=xspace.dim(), key=lambda x: x.min_corner)
    lattice_border_yup = Lattice(dim=xspace.dim(), key=lambda x: x.max_corner)

    lattice_border_ylow.add(xspace)
    lattice_border_yup.add(xspace)

    ylow = []
    yup = []

    # x_minimal = points from 'x' that are strictly incomparable (Pareto optimal)
    ylow_minimal = []
    yup_minimal = []

    # oracle function
    f = oracle.membership()

    error = (epsilon,) * n
    vol_total = xspace.volume()
    vol_yup = 0
    vol_ylow = 0
    vol_border = vol_total
    step = 0

    RootSearch.logger.debug('xspace: {0}'.format(xspace))
    RootSearch.logger.debug('vol_border: {0}'.format(vol_border))
    RootSearch.logger.debug('delta: {0}'.format(delta))
    RootSearch.logger.debug('step: {0}'.format(step))
    RootSearch.logger.debug('incomparable: {0}'.format(incomparable))
    RootSearch.logger.debug('comparable: {0}'.format(comparable))

    # Create temporary directory for storing the result of each step
    tempdir = tempfile.mkdtemp()

    RootSearch.logger.info(
        'Report\nStep, Ylow, Yup, Border, Total, nYlow, nYup, nBorder, BinSearch, nBorder dominated by Ylow, nBorder dominated by Yup')
    while (vol_border >= delta) and (step <= max_step) and (len(border) > 0):
        step = step + 1
        # if RootSearch.logger.isEnabledFor(RootSearch.logger.DEBUG):
        #    RootSearch.logger.debug('border: {0}'.format(border))
        # l.sort(key=Rectangle.volume)

        xrectangle = border.pop()

        lattice_border_ylow.remove(xrectangle)
        lattice_border_yup.remove(xrectangle)

        RootSearch.logger.debug('xrectangle: {0}'.format(xrectangle))
        RootSearch.logger.debug('xrectangle.volume: {0}'.format(xrectangle.volume()))
        RootSearch.logger.debug('xrectangle.norm: {0}'.format(xrectangle.norm()))

        # y, segment
        # y = search(xrectangle.diag(), f, epsilon)
        y, steps_binsearch = binary_search(xrectangle.diag(), f, error)
        RootSearch.logger.debug('y: {0}'.format(y))
        # discovered_segments.append(y)

        # b0 = Rectangle(xrectangle.min_corner, y.low)
        # b1 = Rectangle(y.high, xrectangle.max_corner)
        #
        # ylow.append(b0)
        # yup.append(b1)
        #
        # vol_ylow += b0.volume()
        # vol_yup += b1.volume()

        ################################
        # Every Border rectangle that dominates B0 is included in Ylow
        b0_extended = Rectangle(xspace.min_corner, y.low)
        # border_overlapping_b0 = [rect for rect in border if rect.overlaps(b0_extended)]
        # border_overlapping_b0 = [rect for rect in border_overlapping_b0 if rect.overlaps(b0_extended)]
        ylow_rectangle = Rectangle(y.low, y.low)
        border_overlapping_b0 = lattice_border_ylow.less_equal(ylow_rectangle)
        # border_intersecting_b0 = [b0_extended.intersection(rect) for rect in border_overlapping_b0]

        ## border_nondominatedby_b0 = [rect - b0_extended for rect in border_overlapping_b0]
        # border_nondominatedby_b0 = []
        # for rect in border_overlapping_b0:
        #     border_nondominatedby_b0 += list(rect - b0_extended)

        list_idwc = (idwc(b0_extended, rect) for rect in border_overlapping_b0)
        border_nondominatedby_b0 = set(itertools.chain.from_iterable(list_idwc))
        # border_nondominatedby_b0 = Rectangle.fusion_rectangles(border_nondominatedby_b0)

        # if 'rect' is completely dominated by b0_extended (i.e., rect is strictly inside b0_extended), then
        # set(rect - b0_extended) == {rect}
        # Therefore, 'rect' must be removed from 'non dominated' borders

        border |= border_nondominatedby_b0
        border -= border_overlapping_b0

        lattice_border_ylow.add_list(border_nondominatedby_b0)
        lattice_border_ylow.remove_list(border_overlapping_b0)

        lattice_border_yup.add_list(border_nondominatedby_b0)
        lattice_border_yup.remove_list(border_overlapping_b0)

        # Every Border rectangle that is dominated by B1 is included in Yup
        b1_extended = Rectangle(y.high, xspace.max_corner)
        # border_overlapping_b1 = [rect for rect in border if rect.overlaps(b1_extended)]
        # border_overlapping_b1 = [rect for rect in border_overlapping_b1 if rect.overlaps(b1_extended)]
        yup_rectangle = Rectangle(y.high, y.high)
        border_overlapping_b1 = lattice_border_yup.greater_equal(yup_rectangle)
        # border_intersecting_b1 = [b1_extended.intersection(rect) for rect in border_overlapping_b1]

        ## border_nondominatedby_b1 = [rect - b1_extended for rect in border_overlapping_b1]
        # border_nondominatedby_b1 = []
        # for rect in border_overlapping_b1:
        #     border_nondominatedby_b1 += list(rect - b1_extended)

        list_iuwc = (iuwc(b1_extended, rect) for rect in border_overlapping_b1)
        border_nondominatedby_b1 = set(itertools.chain.from_iterable(list_iuwc))
        # border_nondominatedby_b1 = Rectangle.fusion_rectangles(border_nondominatedby_b1)

        # if 'rect' is completely dominated by b1_extended (i.e., rect is strictly inside b1_extended), then
        # set(rect - b1_extended) == {rect}
        # Therefore, 'rect' must be removed from 'non dominated' borders

        border |= border_nondominatedby_b1
        border -= border_overlapping_b1

        lattice_border_ylow.add_list(border_nondominatedby_b1)
        lattice_border_ylow.remove_list(border_overlapping_b1)

        lattice_border_yup.add_list(border_nondominatedby_b1)
        lattice_border_yup.remove_list(border_overlapping_b1)

        db0 = Rectangle.difference_rectangles(b0_extended, ylow_minimal)
        db1 = Rectangle.difference_rectangles(b1_extended, yup_minimal)

        vol_db0 = sum(b0.volume() for b0 in db0)
        vol_db1 = sum(b1.volume() for b1 in db1)

        # rs = ResultSet([], border_intersecting_b0 + [b0], border_intersecting_b1 + [b1], Rectangle())
        # vol_db0 = rs.volume_ylow() - rs.overlapping_volume_ylow()
        # vol_db1 = rs.volume_yup() - rs.overlapping_volume_yup()

        vol_ylow += vol_db0
        vol_yup += vol_db1

        ylow.extend(db0)
        yup.extend(db1)

        ylow_minimal.append(b0_extended)
        yup_minimal.append(b1_extended)

        RootSearch.logger.debug('b0: {0}'.format(db0))
        RootSearch.logger.debug('b1: {0}'.format(db1))

        RootSearch.logger.debug('ylow: {0}'.format(ylow))
        RootSearch.logger.debug('yup: {0}'.format(yup))

        ################################
        # Every rectangle in 'i' is incomparable for current B0 and for all B0 included in Ylow
        # Every rectangle in 'i' is incomparable for current B1 and for all B1 included in Yup
        ################################

        yrectangle = Rectangle(y.low, y.high)
        i = irect(incomparable, yrectangle, xrectangle)
        # i = pirect(incomparable, yrectangle, xrectangle)
        # l.extend(i)

        border |= i
        RootSearch.logger.debug('irect: {0}'.format(i))

        lattice_border_ylow.add_list(i)
        lattice_border_yup.add_list(i)

        # Remove boxes in the boundary with volume 0
        boxes_null_vol = border[:border.bisect_key_left(0.0)]
        border -= boxes_null_vol
        lattice_border_ylow.remove_list(boxes_null_vol)
        lattice_border_yup.remove_list(boxes_null_vol)

        vol_border = vol_total - vol_yup - vol_ylow

        RootSearch.logger.info('{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}'
                               .format(step, vol_ylow, vol_yup, vol_border, vol_total, len(ylow), len(yup), len(border),
                                       steps_binsearch,
                                       len(border_overlapping_b0), len(border_overlapping_b1)))
        if sleep > 0.0:
            rs = ResultSet(border, ylow, yup, xspace)
            if n == 2:
                rs.plot_2D_light(blocking=blocking, sec=sleep, opacity=0.7)
            elif n == 3:
                rs.plot_3D_light(blocking=blocking, sec=sleep, opacity=0.7)

        if logging:
            rs = ResultSet(border, ylow, yup, xspace)
            name = os.path.join(tempdir, str(step))
            rs.to_file(name)

    return ResultSet(border, ylow, yup, xspace)
コード例 #43
0
ファイル: ls.py プロジェクト: bpuchala/mcapi
def _ls_group(proj, paths, files_only=True, checksum=False, json=False, id=False):
    """
    Construct DataFrame with 'mc ls' results for paths. Also outputs
    the sets of paths that are files or directories (either local or remote).
    
    Arguments:
        files_only: If True, only include files in output DataFrame
        checksum: If True, calculate MD5 checksum of local files and compared to remote
    
    Results:
        (df, files, dirs, remotes):
        
        df: pandas.DataFrame containing:
            'l_mtime', 'l_size', 'l_type', 'r_mtime', 'r_size', 'r_type', 'eq', 'name'
        files: set of local and remote paths that are files
        dirs: set of local and remote paths that are directories
        remotes: set of remote File and Directory objects
        
    """
    path_data = []
    columns = [
        'l_mtime', 'l_size', 'l_type',
        'r_mtime', 'r_size', 'r_type',
        'eq', 'name', 'id']
    data_init = {k:'-' for k in columns}
    files = SortedSet()
    dirs = SortedSet()
    remotes = SortedSet()
    
    for path in paths:
        
        data = copy.deepcopy(data_init)
        data['name'] = os.path.relpath(path, os.getcwd())
        l_checksum = None
        
        # locals
        if os.path.exists(path):
            data['l_mtime'] = time.strftime("%b %Y %d %H:%M:%S", time.localtime(os.path.getmtime(path)))
            data['l_size'] = _humanize(os.path.getsize(path))
            if os.path.isfile(path):
                data['l_type'] = 'file'
                if checksum:
                    with open(path, 'r') as f:
                        l_checksum = hashlib.md5(f.read()).hexdigest()
                files.add(path)
            elif os.path.isdir(path):
                data['l_type'] = 'dir'
                dirs.add(path)
        
        # remotes
        obj = proj.get_by_local_path(path)
        if obj is not None:
            data['r_size'] = _humanize(obj.size)
            if isinstance(obj, mcapi.File):
                if obj.mtime:
                    data['r_mtime'] = obj.mtime.strftime("%b %Y %d %H:%M:%S")
                data['r_type'] = 'file'
                if checksum and l_checksum is not None:
                    data['eq'] = (obj.checksum == l_checksum)
                files.add(path)
                remotes.add(obj)
            elif isinstance(obj, mcapi.Directory):
                if obj.mtime:
                    data['r_mtime'] = obj.time.strftime("%b %Y %d %H:%M:%S")
                data['r_type'] = 'dir'
                dirs.add(path)
                if not files_only:
                    remotes.add(obj)
            data['id'] = obj.id
        
        if not files_only or ('file' in [data['l_type'], data['r_type']]):
            path_data.append(data)
    
    return (pandas.DataFrame.from_records(path_data, columns=columns).sort_values(by='name'), files, dirs, remotes)
 def encode_text(self, text):
     codes = SortedSet()
     for word in text.split():
         codes.add(self.word_to_code(word))
     return codes
コード例 #45
0
ファイル: PointOut.py プロジェクト: lungnahahd/Python_Prac
# 점 뺴기
## 2차 평면 위에 서로 다른 n개의 점이 주어집니다. 이후 m개의 질의가 주어지는데, 각 질의마다는 한 개의 숫자 k가 주어집니다. 각 질의에 대해 주어진 숫자 k보다 x값이 같거나 큰 점 중 x값이 가장 작은 점을 찾아 지우려고 합니다. 
## 만약 x값이 가장 작은 점이 여러 개라면, 그 중 y값이 가장 작은 점을 지우면 됩니다. 각 질의에 대해 해당하는 점을 순서대로 출력하고 지우는 프로그램을 작성해보세요.
### TreeSet 사용 이유 : 큰 것중에 작은 것을 빼고, y 값 역시 동시에 비교해주기 위해 사용



from sortedcontainers import SortedSet

s = SortedSet()

cmd = list(map(int, input().split()))
for i in range(cmd[0]):
    x, y = input().split()
    s.add((int(x),int(y)))

for i in range(cmd[1]):
    numX = int(input())
    where = s.bisect_left((numX,0))
    if where >= len(s):
        print(-1, -1)
    else:
        x, y = s[where]
        print(x, y)
        s.remove(s[where])
コード例 #46
0
ファイル: ChairSit.py プロジェクト: lungnahahd/Python_Prac
# 자리 찾기

### TreeSet 사용 이유 : 의자 위치는 정렬이 필요하고, 계속 조회를 해야하므로 사용

from sortedcontainers import SortedSet

s = SortedSet()      # treeset

cmd = list(map(int,input().split()))
peopleWant = list(map(int, input().split()))
peopleWant.sort(reverse=True)

chairSet = SortedSet()
chair = []
for i in range(cmd[1]):
    chairSet.add(i+1)

resultCount = 0




for i in peopleWant:
    idx = chairSet.bisect_right(i)-1
    if i in chairSet:
        chairSet.remove(i)
        resultCount += 1
    else:
        if idx < 0:
            #print(i)
            break
コード例 #47
0
def multidim_search_opt_1(xspace,
                          oracle,
                          epsilon=EPS,
                          delta=DELTA,
                          max_step=STEPS,
                          blocking=False,
                          sleep=0.0,
                          logging=True):
    # type: (Rectangle, Oracle, float, float, float, bool, float, bool) -> ResultSet

    # Xspace is a particular case of maximal rectangle
    # Xspace = [min_corner, max_corner]^n = [0, 1]^n
    # xspace.min_corner = (0,) * n
    # xspace.max_corner = (1,) * n

    # Dimension
    n = xspace.dim()

    # Set of comparable and incomparable rectangles, represented by 'alpha' indices
    comparable = comp(n)
    incomparable = incomp(n)
    # comparable = [zero, one]
    # incomparable = list(set(alpha) - set(comparable))
    # with:
    # zero = (0_1,...,0_n)
    # one = (1_1,...,1_n)

    # List of incomparable rectangles
    # border = [xspace]
    # border = SortedListWithKey(key=Rectangle.volume)
    border = SortedSet([], key=Rectangle.volume)
    border.add(xspace)

    ylow = []
    yup = []

    # oracle function
    f = oracle.membership()

    error = (epsilon,) * n
    vol_total = xspace.volume()
    vol_yup = 0
    vol_ylow = 0
    vol_border = vol_total
    step = 0

    RootSearch.logger.debug('xspace: {0}'.format(xspace))
    RootSearch.logger.debug('vol_border: {0}'.format(vol_border))
    RootSearch.logger.debug('delta: {0}'.format(delta))
    RootSearch.logger.debug('step: {0}'.format(step))
    RootSearch.logger.debug('incomparable: {0}'.format(incomparable))
    RootSearch.logger.debug('comparable: {0}'.format(comparable))

    # Create temporary directory for storing the result of each step
    tempdir = tempfile.mkdtemp()

    RootSearch.logger.info(
        'Report\nStep, Ylow, Yup, Border, Total, nYlow, nYup, nBorder, BinSearch, nBorder dominated by Ylow, nBorder dominated by Yup')
    while (vol_border >= delta) and (step <= max_step) and (len(border) > 0):
        step = step + 1
        # if RootSearch.logger.isEnabledFor(RootSearch.logger.DEBUG):
        #    RootSearch.logger.debug('border: {0}'.format(border))
        # l.sort(key=Rectangle.volume)

        xrectangle = border.pop()

        RootSearch.logger.debug('xrectangle: {0}'.format(xrectangle))
        RootSearch.logger.debug('xrectangle.volume: {0}'.format(xrectangle.volume()))
        RootSearch.logger.debug('xrectangle.norm: {0}'.format(xrectangle.norm()))

        # y, segment
        # y = search(xrectangle.diag(), f, epsilon)
        y, steps_binsearch = binary_search(xrectangle.diag(), f, error)
        RootSearch.logger.debug('y: {0}'.format(y))
        # discovered_segments.append(y)

        b0 = Rectangle(xrectangle.min_corner, y.low)
        b1 = Rectangle(y.high, xrectangle.max_corner)

        ylow.append(b0)
        yup.append(b1)

        vol_ylow += b0.volume()
        vol_yup += b1.volume()

        RootSearch.logger.debug('b0: {0}'.format(b0))
        RootSearch.logger.debug('b1: {0}'.format(b1))

        RootSearch.logger.debug('ylow: {0}'.format(ylow))
        RootSearch.logger.debug('yup: {0}'.format(yup))

        ################################
        # Every Border rectangle that dominates B0 is included in Ylow
        # Every Border rectangle that is dominated by B1 is included in Yup
        b0_extended = Rectangle(xspace.min_corner, y.low)
        b1_extended = Rectangle(y.high, xspace.max_corner)

        # Every cube in the boundary overlaps another cube in the boundary
        # When cubes from the boundary are moved to ylow or yup, they may still have a complementary cube
        # remaining in the boundary with a non-empty intersection.
        border_overlapping_ylow = [r for r in ylow if r.overlaps(b0_extended)]
        border_overlapping_yup = [r for r in yup if r.overlaps(b1_extended)]

        border_overlapping_b0 = [rect for rect in border if rect.overlaps(b0_extended)]
        # Warning: Be aware of the overlapping areas of the cubes in the border.
        # If we calculate the intersection of b0_extended with all the cubes in the frontier, and two cubes
        # 'a' and 'b' partially overlaps, then the volume of this overlapping portion will be counted twice
        # border_dominatedby_b0 = [rect.intersection(b0_extended) for rect in border_overlapping_b0]
        # Solution: Project the 'shadow' of the cubes in the border over b0_extended.
        border_dominatedby_b0_shadow = Rectangle.difference_rectangles(b0_extended, border_overlapping_b0)

        # The negative of this image returns a set of cubes in the boundary without overlapping.
        # border_dominatedby_b0 will be appended to ylow.
        # Remove the portion of the negative that overlaps any cube that is already appended to ylow
        border_dominatedby_b0 = Rectangle.difference_rectangles(b0_extended,
                                                                border_dominatedby_b0_shadow + border_overlapping_ylow)

        # border_nondominatedby_b0 = [rect - b0_extended for rect in border_overlapping_b0]

        border_nondominatedby_b0 = []
        for rect in border_overlapping_b0:
            border_nondominatedby_b0 += list(rect - b0_extended)

        # border_nondominatedby_b0 = set()
        # for rect in border_overlapping_b0:
        #    border_nondominatedby_b0 |= set(rect - b0_extended)
        # border_nondominatedby_b0 -= set(border_overlapping_b0)

        # if 'rect' is completely dominated by b0_extended (i.e., rect is strictly inside b0_extended), then
        # set(rect - b0_extended) == {rect}
        # Therefore, 'rect' must be removed from 'non dominated' borders

        # border -= border_overlapping_b0
        border |= border_nondominatedby_b0
        border -= border_overlapping_b0

        border_overlapping_b1 = [rect for rect in border if rect.overlaps(b1_extended)]
        # Warning: Be aware of the overlapping areas of the cubes in the border.
        # If we calculate the intersection of b1_extended with all the cubes in the frontier, and two cubes
        # 'a' and 'b' partially overlaps, then the volume of this overlapping portion will be considered twice
        # border_dominatedby_b1 = [rect.intersection(b1_extended) for rect in border_overlapping_b1]
        # Solution: Project the 'shadow' of the cubes in the border over b1_extended.
        border_dominatedby_b1_shadow = Rectangle.difference_rectangles(b1_extended, border_overlapping_b1)

        # The negative of this image returns a set of cubes in the boundary without overlapping.
        # border_dominatedby_b1 will be appended to yup.
        # Remove the portion of the negative that overlaps any cube that is already appended to yup
        border_dominatedby_b1 = Rectangle.difference_rectangles(b1_extended,
                                                                border_dominatedby_b1_shadow + border_overlapping_yup)

        # border_nondominatedby_b1 = [rect - b1_extended for rect in border_overlapping_b1]

        border_nondominatedby_b1 = []
        for rect in border_overlapping_b1:
            border_nondominatedby_b1 += list(rect - b1_extended)

        # border_nondominatedby_b1 = set()
        # for rect in border_overlapping_b1:
        #    border_nondominatedby_b1 |= set(rect - b1_extended)
        # border_nondominatedby_b1 -= set(border_overlapping_b1)

        # if 'rect' is completely dominated by b1_extended (i.e., rect is strictly inside b1_extended), then
        # set(rect - b1_extended) == {rect}
        # Therefore, 'rect' must be removed from 'non dominated' borders

        # border -= border_overlapping_b1
        border |= border_nondominatedby_b1
        border -= border_overlapping_b1

        ylow.extend(border_dominatedby_b0)
        yup.extend(border_dominatedby_b1)

        vol_ylow += sum(b0.volume() for b0 in border_dominatedby_b0)
        vol_yup += sum(b1.volume() for b1 in border_dominatedby_b1)

        ################################
        # Every rectangle in 'i' is incomparable for current B0 and for all B0 included in Ylow
        # Every rectangle in 'i' is incomparable for current B1 and for all B1 included in Yup
        ################################

        yrectangle = Rectangle(y.low, y.high)
        i = irect(incomparable, yrectangle, xrectangle)
        # i = pirect(incomparable, yrectangle, xrectangle)
        # l.extend(i)

        border |= i
        RootSearch.logger.debug('irect: {0}'.format(i))

        # Remove boxes in the boundary with volume 0
        border -= border[:border.bisect_key_left(0.0)]

        vol_border = vol_total - vol_yup - vol_ylow

        RootSearch.logger.info('{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}'
                               .format(step, vol_ylow, vol_yup, vol_border, vol_total, len(ylow), len(yup), len(border),
                                       steps_binsearch,
                                       len(border_overlapping_b0), len(border_overlapping_b1)))
        if sleep > 0.0:
            rs = ResultSet(border, ylow, yup, xspace)
            if n == 2:
                rs.plot_2D_light(blocking=blocking, sec=sleep, opacity=0.7)
            elif n == 3:
                rs.plot_3D_light(blocking=blocking, sec=sleep, opacity=0.7)

        if logging:
            rs = ResultSet(border, ylow, yup, xspace)
            name = os.path.join(tempdir, str(step))
            rs.to_file(name)

    return ResultSet(border, ylow, yup, xspace)
コード例 #48
0
        adj[y].append(x)
        graph['from'].append(x)
        graph['to'].append(y)

    p = []
    p.append((N, N))
    for i in range(1, n + 1):
        p.append((len(adj[i]), i))

    p.sort(reverse=True)

    for i in range(1, n + 1):
        x, y = p[i]
        st = SortedSet()
        for k in adj[y]:
            st.add(col[k])
        for j in range(1, n + 1):
            if ((j in st) == False):
                col[y] = j
                break

    ans = {}

    for i in range(1, n + 1):
        ans[str(i)] = aaa[col[i]]
    results = {'answer': ans}

    ans = str(ans)
    ans = ans.replace("\'", "\"")
    #sys.stdout.write(str(results))
    print(ans)
コード例 #49
0
class Feature(object):
    def __init__(self, software_system, logical_name, size):
        """
        Constructs a new feature specification, initially with no corresponding chunks in the system.
        """
        self._logical_name = logical_name

        self.software_system = software_system
        self.size = size

        self.chunks = SortedSet(key=lambda c: c.logical_name)
        self.tests = SortedSet(key=lambda t: t.logical_name)

    @property
    def logical_name(self):
        return self._logical_name

    @property
    def bugs(self):
        bug_sets = map(lambda c: frozenset(c.bugs), self.chunks)
        return reduce(lambda a, b: a.union(b), bug_sets,
                      SortedSet(key=lambda b: b.fully_qualified_name))

    @property
    def test_coverage(self):
        covered_chunks = SortedSet(
            reduce(lambda a, b: a.union(b),
                   map(lambda t: frozenset(t.chunk_indexes), self.tests),
                   set()))
        return float(len(covered_chunks)) / self.size

    @property
    def tests_per_chunk_ratio(self):

        return 1.0 * len(self.tests) / self.size

    @property
    def dependencies(self):
        all_dependencies = reduce(
            lambda a, b: a.union(b),
            map(lambda c: frozenset(c.dependencies), self.chunks), set())
        external_dependencies = filter(lambda c: c.feature != self,
                                       all_dependencies)
        return SortedSet(external_dependencies, lambda c: c.logical_name)

    @property
    def is_implemented(self):
        return len(self.chunks) >= self.size

    def add_chunk(self, logical_name, local_content=None):
        chunk = Chunk(logical_name, self, local_content)
        self.chunks.add(chunk)
        return chunk

    def extend(self, logical_name, random):
        chunk = self.add_chunk(logical_name)
        chunks_to_modify = random.sample_chunks(self.chunks)
        chunks_to_modify.add(chunk)

        for chunk_to_modify in chunks_to_modify:
            chunk_to_modify.modify(random)

        return chunk

    def debug(self, random, detected_bug=None):
        if detected_bug is None:
            for chunk in self.chunks:
                chunk.debug(random)

        else:
            detected_bugs = SortedSet(self.bugs & {detected_bug},
                                      key=lambda b: b.fully_qualified_name)
            for detected_bug in detected_bugs:
                detected_bug.chunk.debug(random, detected_bug)

    def refactor(self, random):
        random.choose_chunk(self.chunks).refactor(random)

    def add_test(self, logical_name):
        test = Test(logical_name, self)
        self.tests.add(test)
        return test

    def operate(self, random):
        """
        Operates a random sample of the feature's implemented chunks if the feature has been implemented.
        """
        if self.is_implemented:
            for sampled_chunk in random.sample_chunks(self.chunks):
                sampled_chunk.operate(random)

        else:
            raise InoperableFeatureException(self)

    def exercise_tests(self):
        for test in self.tests:
            test.exercise()

    def __str__(self):
        chunk_strings = map(lambda chunk: str(chunk), self.chunks)
        return "f_%d[%s]" % (self._logical_name, ",".join(chunk_strings))

    def __repr__(self):
        return "f_%s" % self._logical_name
コード例 #50
0
ファイル: graphmodel.py プロジェクト: Fading0924/BPChain-CD
def eliminationOrder(gm, orderMethod=None, nExtra=-1, cutoff=inf, priority=None, target=None):
  """Find an elimination order for a graphical model

  Args:
    gm (GraphModel): A graphical model object
    method (str): Heuristic method; one of {'minfill','wtminfill','minwidth','wtminwidth','random'}
    nExtra (int): Randomly select eliminated variable from among the best plus nExtra; this adds
        randomness to the order selection process.  0 => randomly from best; -1 => no randomness (default)
    cutoff (float): Quit early if ``score`` exceeds a user-supplied cutoff value (returning ``target, cutoff``)
    priority (list, optional): Optional list of variable priorities; lowest priority variables are 
        eliminated first.  Useful for mixed elimination models, such as marginal MAP inference tasks.
    target (list): If the identified order is better than cutoff, write it directly into passed ``target`` list

  Returns:
    list: The identified elimination order
    float: The "score" of this ordering

  Using ``target`` and ``cutoff`` one can easily search for better orderings by repeated calls:
  >>> ord, score = eliminationOrder(model, 'minfill', nExtra=2, cutoff=score, target=ord) 
  """
  orderMethod = 'minfill' if orderMethod is None else orderMethod.lower()
  priority = [1 for x in gm.X] if priority is None else priority

  if   orderMethod == 'minfill':    score = lambda adj,Xj: 0.5*sum([len(adj[Xj]-adj[Xk]) for Xk in adj[Xj]])
  elif orderMethod == 'wtminfill':  score = lambda adj,Xj: sum([(adj[Xj]-adj[Xk]).nrStatesDouble() for Xk in adj[Xj]])
  elif orderMethod == 'minwidth':   score = lambda adj,Xj: len(adj[Xj])
  elif orderMethod == 'wtminwidth': score = lambda adj,Xj: adj[Xj].nrStatesDouble()
  elif orderMethod == 'random':     score = lambda adj,Xj: np.random.rand()
  else: raise ValueError('Unknown ordering method: {}'.format(orderMethod))

  adj = [ gm.markovBlanket(Xi) for Xi in gm.X ]  # build MRF

  # initialize priority queue of scores using e.g. heapq or sort
  reverse  = [ (priority[Xi],score(adj,Xi),Xi) for Xi in gm.X ]
  scores = SortedSet( reverse ); 
  totalSize = 0.0
  #_order = np.zeros((len(gm.X),)) #np.array([0 for Xi in gm.X])
  _order = [0]*len(gm.X)

  for idx in range(gm.nvar):
    pick = 0
    Pi,Si,Xi = scores[pick]
    if nExtra >= 0:
      mx = bisect.bisect_right(scores, (Pi,Si,gm.X[-1]))  # get one past last equal-priority & score vars
      pick = min(mx+nExtra, len(scores))                  # then pick a random "near-best" variable
      pick = np.random.randint(pick)
      Pi,Si,Xi = scores[pick]
    del scores[pick]
    _order[idx] = Xi.label        # write into order[idx] = Xi
    totalSize += adj[Xi].nrStatesDouble()
    if totalSize > cutoff: return target,cutoff  # if worse than cutoff, quit with no changes to "target"
    fix = VarSet()
    for Xj in adj[Xi]:
      adj[Xj] |= adj[Xi]
      adj[Xj] -= [Xi]  # TODO adj[Xj].remove(Xi) slightly faster but still unsupported by cython version
      fix |= adj[Xj]   # shouldn't need to fix as much for min-width?
    for Xj in fix:
      Pj,Sj,Xj = reverse[Xj]
      scores.remove(reverse[Xj])
      reverse[Xj] = (Pj,score(adj,Xj),Xj)
      scores.add(reverse[Xj]) # add (Pj,score(adj,Xj),Xj) to heap & update reverse lookup
  if not (target is None): 
    target.extend([None for i in range(len(target),len(_order))])  # make sure order is the right size
    for idx in range(gm.nvar): target[idx]=_order[idx]   # copy result if completed without quitting
  return _order,totalSize
コード例 #51
0
ファイル: chunk.py プロジェクト: twsswt/softdev-workflow
class Chunk(object):
    """
    Represents a chunk of code providing some useful functionality in the system.
    """

    def __init__(self, logical_name, feature, local_content=None):
        self.logical_name = logical_name

        self.feature = feature

        self.local_content = local_content

        self.dependencies = SortedSet(key=lambda d: d.fully_qualified_name)
        self.bugs = SortedSet(key=lambda b: b.logical_name)

        self.bug_count = 0

    def __eq__(self, other):
        if self.local_content != other.local_content:
            return False
        elif self.bugs_logical_names != other.bugs_logical_names:
            return False
        elif self.dependency_logical_names != other.dependency_logical_names:
            return False
        else:
            return True

    def __ne__(self, other):
        return not(self.__eq__(other))

    @property
    def probability_gain_feature_dependency(self):
        return self.feature.software_system.probability_gain_feature_dependency

    @property
    def probability_lose_feature_dependency(self):
        return self.feature.software_system.probability_lose_feature_dependency

    @property
    def probability_gain_system_dependency(self):
        return self.feature.software_system.probability_gain_system_dependency

    @property
    def probability_lose_system_dependency(self):
        return self.feature.software_system.probability_lose_system_dependency

    @property
    def probability_new_bug(self):
        return self.feature.software_system.probability_new_bug

    @property
    def probability_debug_known(self):
        return self.feature.software_system.probability_debug_known

    @property
    def probability_debug_unknown(self):
        return self.feature.software_system.probability_debug_unknown

    @property
    def dependency_logical_names(self):
        return map(lambda d: d.logical_name, self.dependencies)

    @property
    def bugs_logical_names(self):
        return map(lambda b: b.logical_name, self.bugs)

    @property
    def bugs_in_dependencies(self):
        chunk_bug_set = frozenset(map(lambda chunk: frozenset(chunk.bugs), self.dependencies))
        return reduce(lambda bugs_a, bugs_b: bugs_a.union(bugs_b), chunk_bug_set, set())

    @property
    def tests(self):
        return filter(lambda t: self in t.chunks, self.feature.tests)

    def modify(self, random):
        feature_chunks = self.feature.chunks - {self}
        system_chunks = set(self.feature.software_system.chunks.difference(self.feature.chunks))
        self._add_dependencies(random, system_chunks, self.probability_gain_system_dependency)
        self._add_dependencies(random, feature_chunks, self.probability_gain_feature_dependency)

        self.local_content = random.create_local_content()

        self._insert_bugs(random)

    def merge(self, source_chunk, random):
        for dependency in source_chunk.dependencies:
            working_copy_dependency = self.feature.software_system.get_chunk(dependency.fully_qualified_name)
            self.dependencies.add(working_copy_dependency)

        self.modify(random)

    def overwrite_with(self, source_chunk):

        self.local_content = source_chunk.local_content

        self.bugs.clear()
        for old_bug in source_chunk.bugs:
            new_bug = self.get_bug(old_bug.logical_name)
            if new_bug is None:
                self.add_bug(old_bug.logical_name)

        self.dependencies.clear()
        for dependency in source_chunk.dependencies:
            new_dependency = self.feature.software_system.get_chunk(dependency.fully_qualified_name)
            self.dependencies.add(new_dependency)

    def _add_dependencies(self, random, candidate_chunks, threshold):
        for candidate in SortedSet(candidate_chunks, key=lambda c: c.logical_name):
            if random.dependency_should_be_added(threshold):
                self.add_dependency(candidate)

    def add_dependency(self, candidate):
        self.dependencies.add(candidate)

    def _insert_bugs(self, random):
        while random.a_bug_should_be_inserted(self):
            self.add_bug(self.bug_count)
            self.bug_count += 1

    def add_bug(self, logical_name):
        self.bugs.add(Bug(logical_name, self))

    def get_bug(self, logical_name):
        result = filter(lambda bug: bug.logical_name == logical_name, self.bugs)
        if len(result) is 0:
            return None
        else:
            return result[0]

    def refactor(self, random):
        to_remove = set()
        for dependency in self.dependencies:

            if random.dependency_should_be_removed(self, dependency):
                to_remove.add(dependency)

        self.dependencies.difference_update(to_remove)

    def debug(self, random, bug=None):

        if len(self.bugs) == 0:
            return False

        if bug is None or bug not in self.bugs:
            if random.unknown_bug_should_be_removed(self):
                bug = random.choose_bug(self)
                self.bugs.remove(bug)
        elif random.known_bug_should_be_removed(self):
            self.bugs.remove(bug)

    def operate(self, random):
        for bug in self.bugs_in_dependencies.union(self.bugs):
            bug.manifest(random)

    def __str__(self):
        def string_repr_set(iterable):
            return ",".join(map(lambda e: repr(e), iterable))

        feature_dependencies = string_repr_set(filter(lambda c: c.feature == self.feature, self.dependencies))
        system_dependencies = string_repr_set(filter(lambda c: c.feature != self.feature, self.dependencies))

        bugs = ", ".join(map(lambda bug: str(bug), self.bugs))

        return "c_%s:[%s]:[%s]->(in[%s],ex[%s])" % \
               (str(self.logical_name), self.local_content, bugs, feature_dependencies, system_dependencies)

    @property
    def fully_qualified_name(self):
        return "%s.%s" % (str(self.feature.logical_name), str(self.logical_name))

    def __repr__(self):
        return "c%s" % str(self.fully_qualified_name)
コード例 #52
0
count_not_bouncy = 0
count_bouncy = 0
increasing_with_n_digits = SortedSet()
decreasing_with_n_digits = SortedSet()
# both increasing and decreasing, e.g. 777
both_with_n_digits = SortedSet()
for n in range(1, digits_upper_threshold):
    if n % 1000 == 0:
        print("Done {}".format(n))
    is_inc = is_increasing(n)
    is_dec = is_decreasing(n)
    if is_inc or is_dec:
        count_not_bouncy += 1
        if n >= digits_lower_threshold:
            if is_inc and is_dec:
                both_with_n_digits.add(n)
            elif is_inc:
                increasing_with_n_digits.add(n)
            else:
                decreasing_with_n_digits.add(n)
    else:
        count_bouncy += 1
print("n < {} (10^{}) num_not_bouncy: {} num bouncy {}".format(
    digits_upper_threshold, digits_lower_threshold, count_not_bouncy,
    count_bouncy))
# print("{}".format(not_bouncy))
len_all = len(increasing_with_n_digits) + len(decreasing_with_n_digits) + len(
    both_with_n_digits)
# print("{}".format(all))
print("num of just len {} is {}".format(n + 1, len_all))
コード例 #53
0
def test_add():
    temp = SortedSet(range(100), load=7)
    temp.add(100)
    temp.add(90)
    temp._check()
    assert all(val == temp[val] for val in range(101))
コード例 #54
0
class AuctionEngine:
    def __init__(self, auction_manager, trader_address, strategy, frequency):
        self.auction_manager = auction_manager
        self.trader_address = trader_address
        self.strategy = strategy
        self.frequency = frequency
        self._active_auctionlets = SortedSet()
        self._process_lock = threading.Lock()
        self._set_lock = threading.Lock()

    def start(self):
        self._bind_events()
        self._discover_recent_auctionlets()
        while True:
            for auctionlet_id in self._active_auctionlets[:]:
                self._process_auctionlet(auctionlet_id)
            time.sleep(self.frequency)

    def _bind_events(self):
        self.auction_manager.on_new_auction(self._on_new_auctionlet)
        self.auction_manager.on_bid(self._on_bid)
        self.auction_manager.on_split(self._on_split)

    def _discover_recent_auctionlets(self):
        self.auction_manager.discover_recent_auctionlets(
            self._on_recovered_auctionlet)

    def _on_recovered_auctionlet(self, auctionlet_id):
        self._register_auctionlet(auctionlet_id)
        self._process_auctionlet(auctionlet_id)

    def _on_new_auctionlet(self, auctionlet_id):
        self._register_auctionlet(auctionlet_id)
        self._process_auctionlet(auctionlet_id)

    def _on_bid(self, auctionlet_id):
        self._register_auctionlet(auctionlet_id)
        self._process_auctionlet(auctionlet_id)

    def _on_split(self, base_id, new_id, split_id):
        self._register_auctionlet(new_id)
        self._register_auctionlet(split_id)
        self._process_auctionlet(new_id)
        self._process_auctionlet(split_id)

    def _register_auctionlet(self, auctionlet_id):
        with self._set_lock:
            self._active_auctionlets.add(auctionlet_id)

    def _unregister_auctionlet(self, auctionlet_id):
        with self._set_lock:
            try:
                self._active_auctionlets.remove(auctionlet_id)
            except:
                pass

    def _process_auctionlet(self, auctionlet_id):
        with self._process_lock:
            auctionlet = self.auction_manager.get_auctionlet(auctionlet_id)
            if auctionlet is not None:
                self._print_auctionlet(auctionlet_id, auctionlet)
                result = self.strategy.perform(
                    auctionlet,
                    StrategyContext(self.auction_manager.address,
                                    self.trader_address))
                self._print_auctionlet_outcome(auctionlet_id,
                                               result.description)
                if result.forget:
                    self._unregister_auctionlet(auctionlet_id)
            else:
                self._unregister_auctionlet(auctionlet_id)

    def _print_auctionlet(self, auctionlet_id, auctionlet):
        auction = auctionlet.get_auction()
        heading = self._heading(auctionlet_id)
        padding = ' ' * len(heading)
        price = "{0:.8f}".format(auctionlet.sell_amount /
                                 auctionlet.buy_amount)
        logging.info(
            f"{heading} [  selling: {str(auctionlet.sell_amount).rjust(25)} {auction.selling.name()}] [     creator: {auction.creator}]"
        )
        logging.info(
            f"{padding} [ last_bid: {str(auctionlet.buy_amount).rjust(25)} {auction.buying.name()}] [ last_bidder: {auctionlet.last_bidder} (@ {auctionlet.last_bid_time})]"
        )
        logging.info(
            f"{padding} [    price: {price.rjust(21)} {auction.buying.name()}/{auction.selling.name()}] [  parameters: min_incr={auction.min_increase}, min_decr={auction.min_decrease}, ttl={auction.ttl}, reversed={auction.reversed}, expired={auctionlet.expired}]"
        )

    def _print_auctionlet_outcome(self, auctionlet_id, result):
        padding = ' ' * len(self._heading(auctionlet_id))
        logging.info(f"{padding} [  outcome: {result}]")
        logging.info("")

    def _heading(self, auctionlet_id):
        return f"Auctionlet #{auctionlet_id}:"
コード例 #55
0
class AbstractReadyDecorator(AbstractGraphDecorator):
    """
    Wraps a graph and keeps track of tasks that are `ready`.
    
    A task is ready if and only if:
    
     * For each input connection to certain ports: The connected output port has data set with `set_outut_data()`.
       The input ports can be selected with the `port_filter` passed to `__init__`.
     
     * The task is not a sync-point and all sync-point tasks with a lower tick have been executed.
     
     * The task is a sync-point task and all tasks with a lower tick have been executed.
     
    A task is considered to be `executed` once `set_output_data()` has been called.
    """
    
    def __init__(self, g, prefix, port_filter, property_filter, syncpoint_run_last=True):
        """
        :param prefix: Prefix for the task properties used by the implementation
          to keep track of the state. If several decorators of this type
          are wrapped around the same graph, then different prefixes must be used.
        :param port_filter: Function to filter the relevant input ports. The function
          takes three arguments:
           * The graph (`self`)
           * The tick of the task.
           * The name of the port.
          If the function returns `False` Then the port is ignored.
        :param property_filter: Function that filters tasks which are collected.
          The function takes three
           * The graph (`self`)
           * The tick of the task.
           * The properties of the task (`graph.get_task_properties(tick)`).
          Only tasks for which this function returns `True` are returned. The function
          is reevaluated if the properties of a task change.
        :param syncpoint_run_last: If `True` then tasks with syncpoints only
          run once all tasks with a lower tick have completed.
        """
        AbstractGraphDecorator.__init__(self, g)
        self._prefix = prefix
        self._port_filter = port_filter
        self._property_filter = property_filter
        self._syncpoint_run_last = syncpoint_run_last
        
        #: ticks of all tasks that have data for all inputs.
        #: That is, if every output port connected to each input port
        #: had data set with `set_output_data`.
        self._queue = SortedSet()
        
        #: ticks of all tasks with
        #: * `properties["syncpoint"] == True`
        #: * `set_output_data` not yet called.
        self._pending_syncpoints = SortedSet()
        
        #: ticks of all tasks with
        #: * `set_output_data` not yet called.
        self._pending_ticks = SortedSet()
        
        self._collected_prop = self._prefix + "_collected"
        self._count_prop = self._prefix + "_count"
        self._ready_prop = self._prefix + "_ready"
        
        self.g.set_task_property(graph.FINAL_TICK, self._count_prop, 0)
        self.g.set_task_property(graph.FINAL_TICK, self._ready_prop, 0)
        self.g.set_task_property(graph.FINAL_TICK, self._collected_prop, False)
        self._consider(graph.FINAL_TICK)
        self._pending_ticks.add(graph.FINAL_TICK)
        
    def past_all_syncpoints(self):
        """
        Returns `True` if all sync-point tasks have been executed.
        """
        return len(self._pending_syncpoints) == 0
        
    def collect_tasks(self):
        """
        Returns the ticks of all tasks which are ready.
        """
        ticks = set()
        while True:
            tick = self.consume_ready_task()
            if tick is not None:
                ticks.add(tick)
            else:
                break
        return ticks
        
    def consume_ready_task(self):
        """
        Returns the next task which is ready or `None`.
        """
        
        def check_tick_against_sync_point(tick):
            if not self._pending_syncpoints:
                return True # no more sync points
            next_sync_point = self._pending_syncpoints[0]
            
            if tick < next_sync_point:
                # `tick` is not a sync_point and must run
                # before the next sync_point.
                return True
            elif tick == next_sync_point:
                # `tick` is the sync_point
                if self._syncpoint_run_last and self._pending_ticks[0] < next_sync_point:
                    # There are still unfinished tasks that have to run
                    # before it.
                    return False
                else:
                    # It is time to run the sync_point.
                    return True
            else: # tick > next_sync_point
                # has to wait til the sync_point completed
                return False
                
        tick = next(iter(self._queue), None)
        if tick is not None:
            
            if not check_tick_against_sync_point(tick):
                return None
            
            props = self.g.get_task_properties(tick)
            if props.get(self._collected_prop, False):
                raise ValueError("Task %s became ready twice." % tick)
            self.g.set_task_property(tick, self._collected_prop, True)
            self._queue.remove(tick)
        return tick
    
    def was_collected(self, tick):
        """
        Returns if the given tick was collected.
        """
        props = self.g.get_task_properties(tick)
        return props.get(self._collected_prop, False)
        
    
    def add_task(self, tick, task, properties={}):
        properties = dict(properties)
        properties[self._count_prop] = 0
        properties[self._ready_prop] = 0
        properties[self._collected_prop] = False
        self.g.add_task(tick, task, properties=properties)
        self._consider(tick)
        self._pending_ticks.add(tick)
        if properties.get("syncpoint", False):
            self._pending_syncpoints.add(tick)
        
        
    def remove_task(self, tick):
        self.g.remove_task(tick)
        
        if tick in self._queue:
            self._queue.remove(tick)
        if tick in self._pending_syncpoints:
            self._pending_syncpoints.remove(tick)
        if tick in self._pending_ticks:
            self._pending_ticks.remove(tick)
        

    def connect(self, source, dest):
        self.g.connect(source, dest)
        
        if not self._port_filter(self, dest.tick, dest.port):
            return
    
        source_props = self.g.get_task_properties(source.tick)
        dest_props = self.g.get_task_properties(dest.tick)
    
        self.g.set_task_property(dest.tick, self._count_prop, dest_props[self._count_prop] + 1)
        
        if source.port in source_props["out_data"]:
            self.g.set_task_property(dest.tick, self._ready_prop, dest_props[self._ready_prop] + 1)

        self._consider(dest.tick)
            
    def disconnect(self, source, dest):
        self.g.disconnect(source, dest)
            
        if not self._port_filter(self, dest.tick, dest.port):
            return
            
        source_props = self.g.get_task_properties(source.tick)
        dest_props = self.g.get_task_properties(dest.tick)
    
        self.g.set_task_property(dest.tick, self._count_prop, dest_props[self._count_prop] - 1)
        
        if source.port in source_props["out_data"]:
            self.g.set_task_property(dest.tick, self._ready_prop, dest_props[self._ready_prop] - 1)
            
        self._consider(dest.tick)
            
    def set_task_property(self, tick, key, value):
        retval = AbstractGraphDecorator.set_task_property(self, tick, key, value)
        if key == "syncpoint":
            if not value and tick in self._pending_syncpoints:
                self._pending_syncpoints.remove(tick)
            if value:
                self._pending_syncpoints.add(tick)
        self._consider(tick)
        return retval
            
    def set_output_data(self, tick, outputs):
        self.g.set_output_data(tick, outputs)
        
        if tick in self._pending_syncpoints:
            self._pending_syncpoints.remove(tick)
        if tick in self._pending_ticks:
            self._pending_ticks.remove(tick)
        
        for source, dest in self.g.get_out_connections(tick):
            if source.port in outputs:
                
                if not self._port_filter(self, dest.tick, dest.port):
                    continue

                dest_props = self.get_task_properties(dest.tick)
                self.set_task_property(dest.tick, self._ready_prop, dest_props[self._ready_prop] + 1)
                self._consider(dest.tick)
         
    def _consider(self, tick):
        props = self.get_task_properties(tick)
        
        if props.get(self._collected_prop, False):
            # Already collected
            return False
        
        if props[self._count_prop] == props[self._ready_prop]:
            if self._property_filter(self, tick, props):
                should_be_in_queue = True
            else:
                should_be_in_queue = False
        else:
            should_be_in_queue = False
          
        if should_be_in_queue:
            self._queue.add(tick)
        elif tick in self._queue:
            self._queue.remove(tick)
コード例 #56
0
        # return False
        
        #solution by idontknoooo, use SortedSet, time O(Nlog(min(N,k))), space O(min(N,k))
        from sortedcontainers import SortedSet
        # Create SortedSet. `n` is the size of sortedset, max value of `n` is `k` from input
        ss, n = SortedSet(), 0                 
        for i, num in enumerate(nums):
            # index whose value is greater than or equal to `num`
            ceiling_idx = ss.bisect_left(num)  
            # index whose value is smaller than `num`
            floor_idx = ceiling_idx - 1        
            if ceiling_idx < n and abs(ss[ceiling_idx]-num) <= t: # check right neighbour  
                return True  
            if 0 <= floor_idx and abs(ss[floor_idx]-num) <= t: # check left neighbour
                return True
            ss.add(num)
            n += 1
            if i - k >= 0:  # maintain the size of sortedset by finding & removing the earliest number in sortedset
                ss.remove(nums[i-k])
                n -= 1
        return False
    
        # #Right idea but time O(N^2), TLE
        # htb = {}
        # for i, num in enumerate(nums):
        #     for val in htb:
        #         if abs(val-num) <= t and i-htb[val] <= k:
        #             return True
        #     htb[num] = i
        # return False
コード例 #57
0
ファイル: graphmodel.py プロジェクト: ihler/pyGM
def eliminationOrder(gm, orderMethod=None, nExtra=-1, cutoff=inf, priority=None, target=None):
  """Find an elimination order for a graphical model

  Args:
    gm (GraphModel): A graphical model object
    method (str): Heuristic method; one of {'minfill','wtminfill','minwidth','wtminwidth','random'}
    nExtra (int): Randomly select eliminated variable from among the best plus nExtra; this adds
        randomness to the order selection process.  0 => randomly from best; -1 => no randomness (default)
    cutoff (float): Quit early if ``score`` exceeds a user-supplied cutoff value (returning ``target, cutoff``)
    priority (list, optional): Optional list of variable priorities; lowest priority variables are 
        eliminated first.  Useful for mixed elimination models, such as marginal MAP inference tasks.
    target (list): If the identified order is better than cutoff, write it directly into passed ``target`` list

  Returns:
    list: The identified elimination order
    float: The "score" of this ordering

  Using ``target`` and ``cutoff`` one can easily search for better orderings by repeated calls:
  >>> ord, score = eliminationOrder(model, 'minfill', nExtra=2, cutoff=score, target=ord) 
  """
  orderMethod = 'minfill' if orderMethod is None else orderMethod.lower()
  priority = [1 for x in gm.X] if priority is None else priority

  if   orderMethod == 'minfill':    score = lambda adj,Xj: 0.5*sum([len(adj[Xj]-adj[Xk]) for Xk in adj[Xj]])
  elif orderMethod == 'wtminfill':  score = lambda adj,Xj: sum([(adj[Xj]-adj[Xk]).nrStatesDouble() for Xk in adj[Xj]])
  elif orderMethod == 'minwidth':   score = lambda adj,Xj: len(adj[Xj])
  elif orderMethod == 'wtminwidth': score = lambda adj,Xj: adj[Xj].nrStatesDouble()
  elif orderMethod == 'random':     score = lambda adj,Xj: np.random.rand()
  else: raise ValueError('Unknown ordering method: {}'.format(orderMethod))

  adj = [ gm.markovBlanket(Xi) for Xi in gm.X ]  # build MRF

  # initialize priority queue of scores using e.g. heapq or sort
  reverse  = [ (priority[Xi],score(adj,Xi),Xi) for Xi in gm.X ]
  scores = SortedSet( reverse ); 
  totalSize = 0.0
  #_order = np.zeros((len(gm.X),)) #np.array([0 for Xi in gm.X])
  _order = [0]*len(gm.X)

  for idx in range(gm.nvar):
    pick = 0
    Pi,Si,Xi = scores[pick]
    if nExtra >= 0:
      mx = bisect.bisect_right(scores, (Pi,Si,gm.X[-1]))  # get one past last equal-priority & score vars
      pick = min(mx+nExtra, len(scores))                  # then pick a random "near-best" variable
      pick = np.random.randint(pick)
      Pi,Si,Xi = scores[pick]
    del scores[pick]
    _order[idx] = Xi.label        # write into order[idx] = Xi
    totalSize += adj[Xi].nrStatesDouble()
    if totalSize > cutoff: return target,cutoff  # if worse than cutoff, quit with no changes to "target"
    fix = VarSet()
    for Xj in adj[Xi]:
      adj[Xj] |= adj[Xi]
      adj[Xj] -= [Xi]  # TODO adj[Xj].remove(Xi) slightly faster but still unsupported by cython version
      fix |= adj[Xj]   # shouldn't need to fix as much for min-width?
    for Xj in fix:
      Pj,Sj,Xj = reverse[Xj]
      scores.remove(reverse[Xj])
      reverse[Xj] = (Pj,score(adj,Xj),Xj)
      scores.add(reverse[Xj]) # add (Pj,score(adj,Xj),Xj) to heap & update reverse lookup
  if not (target is None): 
    target.extend([None for i in range(len(target),len(_order))])  # make sure order is the right size
    for idx in range(gm.nvar): target[idx]=_order[idx]   # copy result if completed without quitting
  return _order,totalSize
コード例 #58
0
class Intervals:

  def __init__(self, xl=[], regions=None, use_range_data=False, merge=1, is_int=None):
    self.xl = SortedSet()
    self.use_range_data = use_range_data
    self.merge=  merge
    self.is_int = is_int
    if regions is not None:
      xl = [r.getRegion() for r in regions]
    else:
      xl = to_list(xl)
      if len(xl) > 0 and not isinstance(xl[0], list) and not isinstance(xl[0], tuple):
        xl = [xl]

    for x in xl:
      self.add(x)
    glog.debug('Intervals >> %s', self.xl)

  def add(self, *args, **kwargs):
    kwargs = dict(kwargs)
    if self.is_int is not None:
      kwargs['is_int'] = self.is_int

    if self.use_range_data:
      elem = Range1DWithData(*args, **kwargs)
    else:
      elem = Range1D(*args, **kwargs)

    if elem.empty: return
    pos = self.xl.bisect_left(elem)
    cur = None
    next_pos = pos + 1
    if pos > 0:
      prev = self.xl[pos - 1]
      if self.merge and prev.contains(elem.low - 1):
        self.xl.pop(pos - 1)

        ne = prev.union(elem)
        self.xl.add(ne)
        cur = ne
        next_pos = pos
      else:
        assert elem.low >= prev.high

    if cur is None:
      cur = elem
      self.xl.add(elem)

    next = None
    assert cur == self.xl.pop(next_pos - 1)
    next_pos -= 1
    while next_pos < len(self.xl):
      next = self.xl[next_pos]
      if cur.high < next.low:
        break
      self.xl.pop(next_pos)
      cur = cur.union(next)
      cur.high = max(cur.high, next.high)
    self.xl.add(cur)

    return self

  def filter_dataset(self, dataset):
    nx = []
    ny = []
    for i in range(dataset.n):
      if self.should_keep(dataset.x[i]):
        nx.append(dataset.x[i])
        ny.append(dataset.y[i])
    return dataset.make_new('filter', y=ny, x=nx)

  def should_keep(self, v):
    if self.xl is None:
      return True
    for xlow, xhigh in self.xl:
      if xlow <= v < xhigh:
        return True
    return False

  def split_data(self, dataset):
    res = []
    for v in self.xl:
      res.append(dataset[max(0, v.low):v.high])
    return res

  @staticmethod
  def FromIndices(vals, merge_dist=1):
    last = None
    res = Intervals()
    for x in vals:
      if last is None or last.high + merge_dist < x:
        if last is not None:
          res.xl.add(last)
        last = Range1D(x, x, is_int=1)
      else:
        print('mergin here', x, last.low)
      last.high = x
    if last is not None:
      res.xl.add(last)

    return res

  def complement(self, superset):
    superset = Range1D(superset, is_int=1)
    cur = Range1D(superset.low, 0, is_int=1)
    res = Intervals()

    for e in list(self.xl) + [Range1D(superset.high, 0, is_int=1)]:
      cur.high = e.low - 1
      res.xl.add(cur.clone())
      cur.low = e.high + 1
    return res

  def shorten(self, val):
    res = Intervals()
    for x in self.xl:
      res.add(Range1D(x.low + val, x.high - val, is_int=1))
    return res

  def expand(self, val):
    res = Intervals()
    for x in self.xl:
      res.add(Range1D(x.low - val, x.high + val, is_int=1))
    return res

  def filter(self, func):
    res = Intervals()
    for x in self.xl:
      if func(x):
        res.add(x)
    return res

  def shift(self, p):
    res = Intervals()
    for x in self.xl:
      res.add(Range1D(x.low + p, x.high + p))
    return res

  def query(self, q, closest=0):
    pos = self.xl.bisect_left(Range1D(q, math.inf))
    if pos == 0: return None
    if closest or q <= self.xl[pos - 1].high: return self.xl[pos - 1]
    return None

  def query_data_do(self, q, action, fail_if_not=0):
    obj = self.query(q)

    assert obj is not None or not fail_if_not, hex(q)
    if obj is None:
      return None
    return action(obj.data, q - obj.low)

  def query_data_raw(self, q, **kwargs):
    q = self.query(q, **kwargs)
    if q is None: return None
    return q.data

    return found_range.get_data(qr)

  def query_data(self, qr):
    found_range = self.query(qr.low)
    if found_range is None: return bytes([0] * (qr.length() + 1))
    return found_range.get_data(qr)

  def get_ordered_ranges(self):
    return list(self.xl)

  def intersection(self, other):

    prim_ranges = get_primitive_ranges(self.get_ordered_ranges(), other.get_ordered_ranges())
    res = Intervals()
    for e in prim_ranges:
      if self.query(e.low) and other.query(e.low):
        res.add(e)
    return res

  def __str__(self):
    s = io.StringIO()
    s.write('Interval:\n')
    for e in self.xl:
      s.write(str(e) + '\n')
    res = s.getvalue()
    s.close()
    return res

  def group_by(self, tb, res=defaultdict(list)):
    res = copy(res)
    for pos, data in tb:
      res[self.query(pos)].append(data)
    return res
コード例 #59
0
def openFileList(file):
	list = SortedSet([])
	with open(file) as f:
		for l in f.read().splitlines():
			list.add(l.lower())
	return list
コード例 #60
0
ファイル: solver.py プロジェクト: nitinkedia7/satispy
class Solver:
    def __init__(self, var_count, clause_count):
        self.var_count = var_count
        self.clause_count = clause_count
        self.clauses = []
        self.unary_clauses = []
        self.curr_level = 0  # Current depth of the decision tree
        self.max_level = 0

        # Since variables are 1-indexed, size of these lists if (var_count + 1)
        # curr_assignment gives the latest assignment of a variable
        self.curr_assignment = [LiteralState.L_UNASSIGNED] * (var_count + 1)
        self.curr_literal_assignment = [LiteralState.L_UNASSIGNED
                                        ] * (2 * var_count + 1)
        # prev_assignment is used in PHASE SAVING
        self.prev_assignment = [-1] * (var_count + 1)
        # The level the variable was assigned at (if at all)
        self.assignment_level = [-1] * (var_count + 1)
        # A stack of all assigned variables in current path, most recently assigned variables are at top
        self.assigned_till_now = []
        self.assignments_upto_level = [
            0
        ]  # How many assignments had happened upto a level?
        self.conflicts_upto_level = [
            0
        ]  # How many conflicts hence clauses learned upto a level?
        self.antecedent = [-1] * (var_count + 1)
        self.score2var = SortedSet()

        self.bcp_stack = []
        # watch_map: literal -> list of clauses for which this literal is the watcher
        self.watch_map = {}

        # Used in MINISAT decision heuristic explained in decider()
        self.increment_value = 1.0
        self.activity = [0.0] * (var_count + 1)

        # Used in restart optimisation explained in reset_state()
        self.restart_threshold = CONSTANTS.RESTART_LOWER_BOUND
        self.restart_upper_bound = CONSTANTS.RESTART_UPPER_BOUND_BASE

        # Statistics
        self.restart_count = 0
        self.learnt_clauses_count = 0
        self.decision_count = 0
        self.assignments_count = 0
        self.global_max_score = 0.0

    def assign_variable(self, var: int, assignment: LiteralState):
        self.curr_assignment[var] = assignment
        if assignment != LiteralState.L_UNASSIGNED:
            self.prev_assignment[var] = assignment
        self.curr_literal_assignment[get_literal(var)] = assignment
        neg_assignment = LiteralState.L_UNASSIGNED
        if assignment == LiteralState.L_TRUE:
            neg_assignment = LiteralState.L_FALSE
        elif assignment == LiteralState.L_FALSE:
            neg_assignment = LiteralState.L_TRUE
        self.curr_literal_assignment[get_literal(-1 * var)] = neg_assignment

    def bump_var_score(self, var: int, increment_value=0.0):
        if increment_value > 0:
            self.score2var.discard((self.activity[var], var))
            self.activity[var] += increment_value
        self.score2var.add((self.activity[var], var))

    def print_clauses(self):
        print("{} variables, {} clauses".format(self.var_count,
                                                self.clause_count))
        for clause_id, clause in enumerate(self.clauses):
            clause.print(clause_id)

    def print_curr_assignment(self):
        assignment = "State: "
        for var, state in enumerate(self.curr_assignment):
            if (var == 0):
                continue
            assignment += ", {}: {}".format(var, state.value)
        print(assignment)

    # This fn is used to add the given clause to the watchlist of given literal
    def watch_this_clause(self, lit, clause_id):
        if lit in self.watch_map:
            self.watch_map[lit].add(clause_id)
        else:
            self.watch_map[lit] = set([clause_id])

    # Insert a new (input / learned) clause to the cnf
    def insert_clause(self, clause: Clause, first_watch, second_watch):
        self.clauses.append(clause)
        # Setup the two-watch mechanism, both these literals are guaranteed to be unassigned currently
        clause.first_watcher = first_watch
        clause.second_watcher = second_watch
        clause_id = len(self.clauses) - 1
        self.watch_this_clause(clause.get_first_watcher(), clause_id)
        self.watch_this_clause(clause.get_second_watcher(), clause_id)

        # In MINISAT decision heusristic:
        # Score of a varible is the number of clauses in it
        # Since we are inserting a clause, increase the scores of variables in this literal
        for literal in clause.literals:
            var = get_variable(literal)
            self.bump_var_score(var, self.increment_value)
            # self.activity[var] += self.increment_value

    # Function used to assign a literal TRUE in a unary clause
    # These assignments are never reset hence not put in assigned_till_now[]
    def assert_unary_literal(self, lit):
        self.assignments_count += 1
        var = get_variable(lit)
        # Set state of the underlying variable
        if is_negative(lit):
            self.assign_variable(var, LiteralState.L_FALSE)
            # self.curr_assignment[var] = LiteralState.L_FALSE
        else:
            self.assign_variable(var, LiteralState.L_TRUE)
            # self.curr_assignment[var] = LiteralState.L_TRUE
        self.assignment_level[var] = 0  # Always done at ground level

    # Function used to assign a literal TRUE in a non-unary clause
    # Note that current level is important here
    def assert_nonunary_literal(self, lit):
        self.assignments_count += 1
        self.assigned_till_now.append(lit)
        var = get_variable(lit)
        if is_negative(lit):
            self.assign_variable(var, LiteralState.L_FALSE)
            # self.prev_assignment[var] = self.curr_assignment[var] = LiteralState.L_FALSE
        else:
            self.assign_variable(var, LiteralState.L_TRUE)
            # self.prev_assignment[var] = self.curr_assignment[var] = LiteralState.L_TRUE
        self.assignment_level[var] = self.curr_level

    """
    Function to implement Boolean Constant Propagation using Two-watcher optimisation:
    bcp_stack contains all the literals which have been assigned false in current search path.
    Since we know these literals can now change the state of other clauses.
    A naive approach of bcp would be iterate every clause to find a unit/unsatisifed clause.
    If found, repreat the process again else, stop and start guessing some variables in decider()
    """

    def bcp(self) -> (SolverState, int):
        # print("Running BCP with stack", self.bcp_stack)
        conflicting_clause_id = -1
        while (self.bcp_stack):
            # Got a literal with FALSE assignment
            lit = self.bcp_stack.pop()
            assert self.curr_literal_assignment[lit] == LiteralState.L_FALSE
            # assert self.get_literal_status(lit) == LiteralState.L_FALSE

            if lit not in self.watch_map:
                self.watch_map[lit] = set()
            new_watch_list = copy.copy(
                self.watch_map[lit])  # Backup watch list of lit

            # Traverse only the watchlist of that clause to save computation
            for clause_id in self.watch_map[lit]:
                clause = self.clauses[clause_id]

                # This block determines which watcher (1st / 2nd) was lit
                first_watch = clause.get_first_watcher()
                second_watch = clause.get_second_watcher()
                lit_is_first = (lit == first_watch)
                other_watch = second_watch if lit_is_first else first_watch
                # Now that we know lit has been assigned FALSE, we need to find another watcher
                new_clause_state, new_watch_loc = clause.change_watch_location(
                    self, lit_is_first, other_watch)

                # clause has one more literal FALSE, this might change a state
                if (new_clause_state == ClauseState.C_SATISFIED):
                    pass
                elif (new_clause_state == ClauseState.C_UNIT):
                    # If the clause had become unit, we have got another implication here
                    self.assert_nonunary_literal(other_watch)
                    var = get_variable(other_watch)
                    self.antecedent[var] = clause_id
                    self.bcp_stack.append(get_opposite_literal(other_watch))
                elif (new_clause_state == ClauseState.C_CONFLICTING):
                    # All the literals of this clause became false, we have a conflict, need to backtrack
                    # If the conflict occured at ground level, we have a unsatisfiable cnf like (x) ^ (-x)
                    if self.curr_level == 0:
                        return SolverState.S_UNSATISFIED, conflicting_clause_id
                    conflicting_clause_id = clause_id
                    # Clear bcp_stack as a backtrack is coming, which will unassign several variables
                    # As such some information in bcp_state is likely to become stale
                    self.bcp_stack.clear()
                    break
                elif (new_clause_state == ClauseState.C_UNRESOLVED):
                    # The clause is still unresolved as we have found another watcher
                    # Remove this clause from watch list of current lit
                    new_watch_list.remove(clause_id)
                    new_watcher = clause.literals[new_watch_loc]
                    self.watch_this_clause(new_watcher, clause_id)

            # new_watch_list contains the clauses for which lit is still the watcher
            # Note that in case of backtrack, we dot need to revert the watchers in two-watcher method
            # since in backtracking, some variables will be unassigned, enforcing the two-watch invariant
            self.watch_map[lit].clear()
            self.watch_map[lit] = new_watch_list
            if (conflicting_clause_id >= 0):
                return SolverState.S_CONFLICT, conflicting_clause_id
        return SolverState.S_UNRESOLVED, conflicting_clause_id

    """
    This function is for the PHASE-SAVING heuristic
    In decider() after the variable to be guessed has been selected, we then
    need it set it to TRUE of FALSE. Phase-saving says we should set it to our
    previous assignment if any.  
    """

    def get_lit_memoised(self, var: int) -> int:
        prev_state = self.prev_assignment[var]
        if (prev_state == LiteralState.L_TRUE):
            return get_literal(var)
        else:
            return get_literal(-1 * var)

    """
    decide() function selects the next variable to be guessed and the guessed value.
    Based on MINISAT decision heuristic. Results in increment of current level.  
    Score of a varible is the number of clauses in it.
    """

    def decide(self) -> SolverState:  # MINISAT based decision heuristic
        # print("Running decider")
        # self.print_curr_assignment()
        # print("Activity: ", self.activity)
        # Find an unassigned one with maximum score
        # Some inputs have unused variables, so we select only those with positive score.
        selected_lit = 0
        unassigned_var_found = False
        while self.score2var:
            max_score, var = self.score2var.pop()
            self.global_max_score = max(self.global_max_score, max_score)
            if self.curr_assignment[var] == LiteralState.L_UNASSIGNED:
                unassigned_var_found = True
                selected_lit = self.get_lit_memoised(var)
                break

        if not unassigned_var_found:
            return SolverState.S_SATISFIED
        # print(selected_lit, selected_var, max_activity_till_now)
        assert selected_lit != 0
        self.decision_count += 1
        self.curr_level += 1
        # We need to track this new assignment
        if (self.curr_level > self.max_level):
            # This branch is separate since we are at a new decision level,
            # so push_back is required instead of update
            self.max_level = self.curr_level
            self.assignments_upto_level.append(len(self.assigned_till_now))
            self.conflicts_upto_level.append(self.learnt_clauses_count)
        else:
            self.assignments_upto_level[self.curr_level] = len(
                self.assigned_till_now)
            self.conflicts_upto_level[
                self.curr_level] = self.learnt_clauses_count

        # Now we assign the literal as TRUE, and since put the (FALSE) opposite literal to bcp stack
        self.assert_nonunary_literal(selected_lit)
        self.bcp_stack.append(get_opposite_literal(selected_lit))
        return SolverState.S_UNRESOLVED

    """
    analyse_conflict() takes a conflicting clause and returns the level to backtrack to, and a learned clause
    We use the nearest UIP (Unique Implication Point) finding method as highlighted in Kroening's book.
    """

    def analyze_conflict(self, conflicting_clause: Clause) -> (int, int):
        # print("Running analyse_conflict")
        curr_literals = [lit for lit in conflicting_clause.literals]
        learned_clause = Clause([])
        backtrack_level = 0  # to be returned by this function
        to_resolve_count = 0
        watch_lit = 0  # a watcher for the new learned literal

        marked = [False] * (self.var_count + 1)
        trail_index = len(self.assigned_till_now) - 1
        resolve_lit = 0
        resolve_var = 0
        iter = 0
        """
        This loop outputs the learned clause, it works as follows:
        Invariant 1: curr_literals is the clause to be fused into learned_clause
        Invariant 2: learned caluse contains exactly one variable assigned at current level (UIP)
        All other literals are assigned before.
        """
        while (iter == 0 or to_resolve_count > 0):
            iter += 1
            for lit in curr_literals:
                var = get_variable(lit)
                if marked[var]:
                    continue
                marked[var] = True
                if (self.assignment_level[var] == self.curr_level):
                    to_resolve_count += 1
                else:
                    learned_clause.insert_literal(lit)
                    if (self.assignment_level[var] > backtrack_level):
                        # watch_lit: 2nd highest assigment level, first is UIP
                        backtrack_level = self.assignment_level[var]
                        watch_lit = len(learned_clause.literals) - 1
            # Find a variable to be resolved by traversing the recently assigned literals first
            while (trail_index >= 0):
                resolve_lit = self.assigned_till_now[trail_index]
                resolve_var = get_variable(resolve_lit)
                trail_index -= 1
                if marked[resolve_var]:
                    break
            marked[resolve_var] = False
            to_resolve_count -= 1
            if not to_resolve_count:
                # Just one literal remaining with current level assignment, we are done
                continue
            antecedent_id = self.antecedent[resolve_var]
            curr_literals = [
                lit for lit in self.clauses[antecedent_id].literals
                if lit != resolve_lit
            ]

        # The learned clause becomes an unit clause after backtracking
        # This is because every other literal in the learned clause was assigned before
        # the backtrack level
        # resolve_lit is an UIP
        self.learnt_clauses_count += 1
        opposite_resolv_lit = get_opposite_literal(resolve_lit)
        learned_clause.insert_literal(opposite_resolv_lit)
        self.increment_value /= CONSTANTS.VAR_DECAY_RATE
        if learned_clause.is_unary:
            # Not that we are inserting to bcp_stack without asserting UIP
            # Asserting will be done immediately after backtrack (see backtrack())
            self.bcp_stack.append(resolve_lit)
            self.unary_clauses.append(learned_clause)
        else:
            self.bcp_stack.append(resolve_lit)
            self.insert_clause(learned_clause, watch_lit,
                               len(learned_clause.literals) - 1)
        # for lit in learned_clause.literals:
        #     var = get_variable(lit)
        #     print("({}, {})".format(var, self.assignment_level[var]))
        return backtrack_level, opposite_resolv_lit

    # RESTART heuristic, reset all assignments except ground level and start afresh
    # Note that learned claused are not deleted only we start assignments from the beginning
    def reset_state(self):
        # print("Restart")
        """
        The threshold system works as follows eg. (chainsaw graph)
        1. We have a range [1, 10]. Threshold increases after every restart till it crosses the ub
        2. At that point the threshold is rest and the range is also increased to let it go even higher
        """
        self.restart_count += 1
        self.restart_threshold = int(self.restart_threshold *
                                     CONSTANTS.THRESHOLD_MULTIPLIER)
        if (self.restart_threshold > self.restart_upper_bound):
            self.restart_threshold = CONSTANTS.RESTART_LOWER_BOUND
            self.restart_upper_bound = int(self.restart_upper_bound *
                                           CONSTANTS.THRESHOLD_MULTIPLIER)

        # Resets are similar to backtrack() function below, except that it resets evrything to ground level
        for var in range(1, self.var_count + 1):
            if (self.assignment_level[var] > 0):
                self.assign_variable(var, LiteralState.L_UNASSIGNED)
                # self.curr_assignment[var] = LiteralState.L_UNASSIGNED
                self.bump_var_score(var)

        self.bcp_stack.clear()
        self.assigned_till_now.clear()
        self.assignments_upto_level = [0]
        self.conflicts_upto_level = [0]
        self.curr_level = 0
        self.max_level = 0

    # Function to backtrack based on the output of analyse_conflict()
    def backtrack(self, k: int, uip_lit):
        # print("Running backtrack")
        # Invoke restart heuristic if too many clauses have been learnt after backtrack target level
        if k > 0 and (self.learnt_clauses_count - self.conflicts_upto_level[k]
                      > self.restart_threshold):
            self.reset_state()
            return
        # Iterate over the variables assigned at level >= k + 1 and unassign them
        for index in range(self.assignments_upto_level[k + 1],
                           len(self.assigned_till_now)):
            var = get_variable(self.assigned_till_now[index])
            if (self.assignment_level[var] > k):
                self.assign_variable(var, LiteralState.L_UNASSIGNED)
                # self.curr_assignment[var] = LiteralState.L_UNASSIGNED
                self.bump_var_score(var)

        # analyse_function() returns an asserting clause with the UIP just ready for assignment
        # This helps to immediately put the learnt clause into practice
        self.assigned_till_now = self.assigned_till_now[:self.
                                                        assignments_upto_level[
                                                            k + 1]]
        self.curr_level = k
        if k == 0:
            # We had learnt a unary clause
            self.assert_unary_literal(uip_lit)
        else:
            self.assert_nonunary_literal(uip_lit)
        self.antecedent[get_variable(uip_lit)] = len(self.clauses) - 1

    # Function to verify output assignment if any
    def verify_assignment(self):
        non_true_clauses = []
        all_clauses = self.clauses + self.unary_clauses
        # Every clause including learnt and unary must have atleast one TRUE literal
        for clause in all_clauses:
            true_literal_found = False
            for lit in clause.literals:
                if self.curr_literal_assignment[lit] == LiteralState.L_TRUE:
                    # if (self.get_literal_status(lit) == LiteralState.L_TRUE):
                    true_literal_found = True
                    break
            if not true_literal_found:
                non_true_clauses.append(clause)
        if not non_true_clauses:
            print("AC, All clauses evaluate to true under given assignment")
        else:
            print("WA, {} unsatisfied clauses found".format(
                len(non_true_clauses)))

    """
    Function implementing the standard CDCL framework:
        1. [Outer Loop] Run BCP and decide() alternately, bcp first because of unary clauses
        2. [INNER LOOP] Run till BCP gives UNRESOLVED result on which point guesswork must be done.
        If bcp encounters conflict a analyse, backtrack pair is done
    """

    def run_cdcl(self) -> SolverState:
        result: SolverState
        while (True):
            while (True):
                result, conflicting_clause_id = self.bcp()
                # print("BCP result was {}".format(result))
                if (result == SolverState.S_UNSATISFIED):
                    return result
                if (result == SolverState.S_CONFLICT):
                    assert conflicting_clause_id != -1
                    backtrack_level, uip_lit = self.analyze_conflict(
                        self.clauses[conflicting_clause_id])
                    # print("Analyze result was k = {}, uip = {}".format(backtrack_level, uip_lit))
                    self.backtrack(backtrack_level, uip_lit)
                else:
                    break
            result = self.decide()
            # print("Decide result was {}".format(result))
            if (result == SolverState.S_UNSATISFIED
                    or result == SolverState.S_SATISFIED):
                return result

    # Wrapper function to print the result of the CDCL framework
    def solve(self):
        # print("Solving")
        result: SolverState = self.run_cdcl()
        if (result == SolverState.S_SATISFIED):
            print("SATISFIABLE")
            self.verify_assignment()
            with open("assignment.txt", 'w') as assignment_file:
                for var, state in enumerate(self.curr_assignment):
                    if (var == 0):
                        assignment_file.write("State: ")
                        continue
                    assignment_file.write("{} ".format(
                        -1 * var if state == LiteralState.L_FALSE else var))
        else:
            print("UNSATISFIABLE")

    def print_statistics(self, solve_time):
        print("## Statistics: ")
        print("# Restarts: ", self.restart_count)
        print("# Learned clauses: ", self.learnt_clauses_count)
        print("# Decisions: ", self.decision_count)
        print("# Implications: ", self.assignments_count - self.decision_count)
        print("# Max score: ", self.global_max_score)
        print("# Time (s): ", solve_time)