class PAGERANK_MARKING_FAST(page_replacement_algorithm):

    def __init__(self, N):
        self.T = Disk(N)
        self.H = Disk(N)
        self.N = N
        self.marked = set()
        self.G = {} ## local access graph
        self.last_request = -1
        self.first_request = False
        self.PR = {}
    def get_N(self) :
        return self.N

    def request(self,page) :
        # print('request: ', page)
        page_fault = False

        if not self.first_request :
            self.__add_edge(self.last_request, page)

        self.last_request = page
        self.first_request = False

        if page in self.T  :
            ## Mark page
            self.marked.add(page)
        else :
            if page in self.H :
                self.H.delete(page)

            # Start a new phase when all pages are marked and a page fault occurs
            # Unmark all the pages
            if len(self.marked) == self.N :
                self.marked.clear()
                self.PR = self.compute_pagerank(page)

            if self.T.size() == self.N :
                ## Get the set of unmarked pages
                U = set(self.T.get_data()) - self.marked

                # Compute the page rank of all pages
                # self.PR = self.compute_pagerank(page)

                ## Choose a page with minimum pagerank
                least_pagerank_page = -1
                for u in U :
                    if least_pagerank_page == -1 or self.PR[u] < self.PR[least_pagerank_page] :
                        least_pagerank_page = u

                ## Delete page from cache
                self.T.delete(least_pagerank_page)

                ## Remove least resent page from history
                if self.H.size() == self.N :
                    u = self.H.deleteFront()
                    if u is not None and page in self.G :
                        # print('G.pop (',u,')')
                        self.G.pop(u, None)

                ## Move discarted page to history
                self.H.add(least_pagerank_page)

            ## Mark page and add to T
            self.marked.add(page)
            self.T.add(page)

            ## Page fault is True
            page_fault = True

        return page_fault

    def __add_edge(self, u,v) :
        if u not in self.G :
            self.G[u] = set()
        if v not in self.G :
            self.G[v] = set()

        self.G[u] = self.G[u] | {v}
        self.G[v] = self.G[v] | {u}

    def __get_adj_matrix(self) :
        ## Mapping
        node_id = {}
        node_name = {}
        for i,node in enumerate(self.G) :
            node_id[node] = i
            node_name[i] = node

        A = np.zeros((len(node_id),len(node_id)))
        for u in self.G :
            adj = list(self.G[u])
            for v in adj:
                if v in self.G :
                    u_id = node_id[u]
                    v_id = node_id[v]
                    A[u_id,v_id] = 1
                    A[v_id,u_id] = 1
                else :
                    self.G[u] = self.G[u] - {v}

        return A,node_id,node_name

    def __mult_matrix(self,A,n) :
        B = np.eye(len(A))
        while n > 0 :
            if n % 2 == 1 :
                B = np.matmul(B,A)
            A = np.matmul(A,A)
            n = n / 2
        return B

    def compute_pagerank(self, init_page) :
        A, node_id, node_name = self.__get_adj_matrix()
        u = node_id[init_page]
        n = len(A)

        ## Transportation vector
        E = np.zeros(n)
        E[u] = 1

        # ranks_per_page = pr.compute(A,teleport_vector=tv)
        pr = Pagerank()
        R = pr.compute_local(A,E)

        PR = {}
        for v,pr in enumerate(R) :
            PR[node_name[v]] = pr
        return PR

    def page_label(self,page):
        lab = "%s(%.1f)" % (page, self.PR[page] if page in self.PR else 0)
        return lab

    def page_color(self,page) :
        if page in self.marked :
            return 1 ## Red
        else :
            return 0 # white

    def debug(self) :
        X = []
        for u in self.get_data() :
            X.append((self.P[u],u))

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.T.get_data(), self.H.get_data()]
Exemple #2
0
class ARC(page_replacement_algorithm):
    def __init__(self, N):
        self.N = N
        self.T1 = Disk(N)
        self.T2 = Disk(N)
        self.B1 = Disk(N)
        self.B2 = Disk(2 * N)
        self.P = 0

        self.time = 0
        self.X = []
        self.Y = []

        self.unique = {}
        self.unique_cnt = 0
        self.pollution_dat_x = []
        self.pollution_dat_y = []

    def getWeights(self):
        #         return np.array([self. X, self.Y1, self.Y2,self.pollution_dat_x,self.pollution_dat_y ]).T
        return np.array([self.pollution_dat_x, self.pollution_dat_y]).T

    def getStats(self):
        d = {}
        d['pollution'] = np.array([self.pollution_dat_x,
                                   self.pollution_dat_y]).T
        return d

    def visualize(self, plt):
        #         l1, = plt.plot(self.X,self.Y,'r-', label='ARC p-value')
        #         return [l1]
        return []

    def get_N(self):
        return self.N

    def request(self, page):
        page_fault = False
        self.time += 1
        #         self.X.append(self.time)
        #         self.Y.append(1.0*self.P / self.N)
        t1 = self.T1.size()
        t2 = self.T2.size()
        b1 = self.B1.size()
        b2 = self.B2.size()

        assert t1 + t2 <= self.N, 'Error: t1+t2 should not be bigger than self.N. t1+t2=%d+%d=%d' % (
            t1, t2, t1 + t2)
        assert t1 + b1 <= self.N, 'Error: t1+b1 should not be bigger than self.N. t1+b1=%d+%d=%d' % (
            t1, b1, t1 + b1)
        assert t1 + t2 + b1 + b2 <= 2 * self.N, 'Error: t1+t2+b1+b2 should not be bigger than 2*self.N. t1+t2+b1+b2=%d+%d+%d+%d=%d' % (
            t1, t2, b1, b2, t1 + t2 + b1 + b2)

        if page in self.T1 or page in self.T2:
            if page in self.T1:
                assert self.T1.delete(page)
            if page in self.T2:
                assert self.T2.delete(page)

            assert self.T2.add(page), 'failed adding to T2 at Case 1'

        elif self.B1.inDisk(page):

            if self.B2.size() > self.B1.size():
                r = self.B2.size() / self.B1.size()
            else:
                r = 1
            self.P = min(self.P + r, self.N)
            self.__replace(page)
            assert self.B1.delete(page)
            assert self.T2.add(page), 'failed adding to T2 at case B1'
            page_fault = True
        elif self.B2.inDisk(page):
            if self.B1.size() > self.B2.size():
                r = self.B1.size() / self.B2.size()
            else:
                r = 1
            self.P = max(self.P - r, 0)
            self.__replace(page)
            assert self.B2.delete(page)
            assert self.T2.add(page), 'failed adding to T2  at case B2'
            page_fault = True
        else:
            if t1 + b1 == self.N:
                if t1 < self.N:
                    assert self.B1.deleteFront(
                    ) is not None, 'Error deleting front of B1'
                    self.__replace(page)
                else:
                    assert self.T1.deleteFront(
                    ) is not None, 'Error deleting front of T1'
            elif t1 + b1 < self.N:
                if t1 + t2 + b1 + b2 >= self.N:
                    if t1 + t2 + b1 + b2 == 2 * self.N:
                        assert self.B2.deleteFront(
                        ) is not None, 'Error deleting front of B2'
                    self.__replace(page)

            # Add page to the MRU position in T1
            assert self.T1.add(page), 'failed adding page to T1 at case 4'
            page_fault = True

        if page_fault:
            self.unique_cnt += 1

        self.unique[page] = self.unique_cnt

        if self.time % self.N == 0:
            pollution = 0
            for pg in self.T1.getData() + self.T2.getData():
                if self.unique_cnt - self.unique[pg] >= 2 * self.N:
                    pollution += 1
            self.pollution_dat_x.append(self.time)
            self.pollution_dat_y.append(100 * pollution / self.N)

        return page_fault

    def __replace(self, x):
        if self.T1.size() > 0 and (self.T1.size() > self.P or
                                   (self.B1.inDisk(x)
                                    and self.T1.size() == int(self.P))):
            y = self.T1.deleteFront()
            assert y is not None, 'Error deleting front of T1 in replace (Case 1)'
            assert self.B1.add(
                y), 'failed adding page to B1 at replace 1(Case 1)'
        else:
            y = self.T2.deleteFront()
            assert y is not None, 'Error deleting front of T2 in replace (Case 2)'
            assert self.B2.add(
                y), 'failed adding page to B2 at replace 1(Case 2)'
#             s1 = self.T1.size()+self.T2.size()
#             s2 = self.B1.size()+self.B2.size()
#             print('sizes = %d + %d + %d + %d = %d + %d = %d' % (self.T1.size(),self.T2.size(),self.B1.size(),self.B2.size(), s1,s2,s1+s2))
#             print('failed adding at replace 2 %d ' %y)

    def get_data(self):
        return [
            self.T1.get_data(),
            self.T2.get_data(),
            self.B1.get_data(),
            self.B2.get_data()
        ]

    def get_list_labels(self):
        return ['T1', 'T2', 'B1', 'B2']
Exemple #3
0
class ARC(page_replacement_algorithm):
    def __init__(self, N):
        self.T = []
        self.N = N
        self.T1 = Disk(N)
        self.T2 = Disk(N)
        self.B1 = Disk(N)
        self.B2 = Disk(2 * N)
        self.P = 0

    def get_N(self):
        return self.N

    def request(self, page):
        page_fault = False
        #if inList(self.T, page):
        if self.T1.inDisk(page) or self.T2.inDisk(page):
            #self.T = moveToMRU(self.T,page)
            if page in self.T1:
                self.T1.delete(page)
            if page in self.T2:
                self.T2.delete(page)

            if not self.T2.add(page):
                print('failed adding at Case 1')

        elif self.B1.inDisk(page):
            if self.B2.size() > self.B1.size():
                r = self.B2.size() / self.B1.size()
            else:
                r = 1
            self.P = min(self.P + r, self.N)
            self.__replace(page)
            self.B1.delete(page)
            if not self.T2.add(page):
                print('failed adding at B1')

            page_fault = True
        elif self.B2.inDisk(page):
            if self.B1.size() > self.B2.size():
                r = self.B1.size() / self.B2.size()
            else:
                r = 1
            self.P = min(self.P - r, 0)
            self.__replace(page)
            self.B2.delete(page)
            if not self.T2.add(page):
                print('failed adding at B2')
            page_fault = True
        else:
            t1 = self.T1.size()
            t2 = self.T2.size()
            b1 = self.B1.size()
            b2 = self.B2.size()

            if t1 + b1 == self.N:
                if t1 < self.N:
                    self.B1.deleteFront()
                    self.__replace(page)
                else:
                    self.T1.deleteFront()
            elif t1 + b1 < self.N:
                if t1 + t2 + b1 + b2 >= self.N:
                    if t1 + t2 + b1 + b2 == 2 * self.N:
                        self.B2.deleteFront()
                    self.__replace(page)

            # Add page to the MRU position in T1
            # self.T.append(page)
            if not self.T1.add(page):
                print('failed adding at case 4')
            page_fault = True

        return page_fault

    def __replace(self, x):
        if self.T1.size() > 0 and (self.T1.size() > self.P or
                                   (self.B1.inDisk(x)
                                    and self.B1.size() == self.P)):
            y = self.T1.deleteFront()
            if not y == None:

                if not self.B1.add(y):
                    print('failed adding at replace 1')
        else:
            y = self.T2.deleteFront()
            if not y == None:
                if not self.B2.add(y):
                    print('sizes = %d %d %d %d' %
                          (self.T1.size(), self.T2.size(), self.B1.size(),
                           self.B2.size()))
                    print('failed adding at replace 2 %d ' % y)

    def get_data(self):
        return [
            self.T1.get_data(),
            self.T2.get_data(),
            self.B1.get_data(),
            self.B2.get_data()
        ]

    def get_list_labels(self):
        return ['T1', 'T2', 'B1', 'B2']
class ARCOPT(page_replacement_algorithm):
    def __init__(self, N, traces):
        self.T = []
        self.N = N
        self.T1 = Disk(N)
        self.T2 = Disk(N)
        self.B1 = Disk(N)
        self.B2 = Disk(2 * N)
        self.P = 0

        self.page_request_time = {}

        ##
        for i, p in enumerate(traces):
            if p not in self.page_request_time:
                self.page_request_time[p] = Queue.Queue()
            self.page_request_time[p].put(i)

    def get_N(self):
        return self.N

    def request(self, page):

        x = self.page_request_time[page].get()

        #print self.T1.size(), self.T2.size()
        page_fault = False
        #if inList(self.T, page):
        if self.T1.inDisk(page) or self.T2.inDisk(page):
            #self.T = moveToMRU(self.T,page)
            if page in self.T1:
                self.T1.delete(page)
            if page in self.T2:
                self.T2.delete(page)

            if not self.T2.add(page):
                print('failed adding at Case 1')

        elif self.B1.inDisk(page):
            self.__replace(page)
            self.B1.delete(page)
            if not self.T2.add(page):
                print('failed adding at B1')

            page_fault = True
        elif self.B2.inDisk(page):
            self.__replace(page)
            self.B2.delete(page)
            if not self.T2.add(page):
                print('failed adding at B2')
            page_fault = True
        else:
            t1 = self.T1.size()
            t2 = self.T2.size()
            b1 = self.B1.size()
            b2 = self.B2.size()

            if t1 + b1 == self.N:
                if t1 < self.N:
                    self.B1.deleteFront()
                    self.__replace(page)
                else:
                    self.T1.deleteFront()
            elif t1 + b1 < self.N:
                if t1 + t2 + b1 + b2 >= self.N:
                    if t1 + t2 + b1 + b2 == 2 * self.N:
                        self.B2.deleteFront()
                    self.__replace(page)

            # Add page to the MRU position in T1
            # self.T.append(page)
            if not self.T1.add(page):
                print('failed adding at case 4')
            page_fault = True

        return page_fault

    def __replace(self, x):

        if self.T1.size() == 0:
            y = self.T2.deleteFront()
            if not y == None:
                self.B2.add(y)
        elif self.T2.size() == 0:
            y = self.T1.deleteFront()
            if not y == None:
                self.B1.add(y)
        else:

            t1_page = self.T1.getIthPage(0)
            t2_page = self.T2.getIthPage(0)

            if not self.page_request_time[t1_page].empty():
                page1_time = self.page_request_time[t1_page].queue[0]
            else:
                page1_time = int(1e15)

            if not self.page_request_time[t2_page].empty():
                page2_time = self.page_request_time[t2_page].queue[0]
            else:
                page2_time = int(1e15)

            if page1_time > page2_time:
                y = self.T2.deleteFront()
                if not y == None:
                    self.B2.add(y)
            else:
                y = self.T1.deleteFront()
                if not y == None:
                    self.B1.add(y)

    def get_data(self):
        return [
            self.T1.get_data(),
            self.T2.get_data(),
            self.B1.get_data(),
            self.B2.get_data()
        ]

    def get_list_labels(self):
        return ['T1', 'T2', 'B1', 'B2']
Exemple #5
0
class FAR(page_replacement_algorithm):
    def __init__(self, N):
        self.T = Disk(N)
        self.N = N
        self.marked = set()
        self.G = {}  ## local access graph
        self.last_request = -1
        self.first_request = False

    def get_N(self):
        return self.N

    def request(self, page):
        # print('request: ', page)
        page_fault = False

        if not self.first_request:
            self.__add_edge(self.last_request, page)

        self.last_request = page
        self.first_request = False

        if page in self.T:
            ## Mark page
            self.marked.add(page)
        else:

            # Start a new phase when all pages are marked and a page fault occurs
            # Unmark all the pages
            if len(self.marked) == self.N:
                self.marked.clear()

            if self.T.size() == self.N:
                ## Get the set of unmarked pages
                U = set(self.T.get_data()) - self.marked

                # Compute the page distance
                # self.PR = self.compute_pagerank(page)
                dist = self.__distance_bfs(page)

                furthest_page = -1
                first = True
                for u in U:
                    # print("u = ",u)
                    if first or dist[u] > dist[furthest_page]:
                        furthest_page = u
                        first = False

                ## Delete page from cache
                self.T.delete(furthest_page)

                ## Remove furthest page from history
                if furthest_page in self.G:
                    # print('G.pop (',u,')')
                    self.G.pop(furthest_page, None)

            ## Mark page and add to T
            self.marked.add(page)
            self.T.add(page)

            ## Page fault is True
            page_fault = True

        return page_fault

    def __distance_bfs(self, u):
        q = Q.Queue()
        dist = {}
        q.put(u)
        dist[u] = 0
        while not q.empty():
            u = q.get()
            # print("u = ", u)
            adj = self.G[u]
            for v in adj:
                if v not in dist and v in self.G:
                    if v in self.G:
                        dist[v] = dist[u] + 1
                        q.put(v)
                    else:
                        self.G[u] = self.G[u] - {v}
                    # print("\tv = ", v)
        return dist

    def __add_edge(self, u, v):
        if u not in self.G:
            self.G[u] = set()
        if v not in self.G:
            self.G[v] = set()

        self.G[u] = self.G[u] | {v}
        self.G[v] = self.G[v] | {u}

    def page_label(self, page):
        lab = "%s" % (page)
        return lab

    def page_color(self, page):
        if page in self.marked:
            return 1  ## Red
        else:
            return 0  # white

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.T.get_data()]
Exemple #6
0
class WALK_MARKING_SLOW(page_replacement_algorithm):
    def __init__(self, N):
        self.T = Disk(N)
        self.H = Disk(N)
        self.N = N
        self.marked = set()
        self.G = {}  ## local access graph

        self.is_first_request = True
        self.last_request = -1

        self.page_probability = {}

    def get_N(self):
        return self.N

    def request(self, page):
        # print('request: ', page)
        page_fault = False

        if not self.is_first_request:
            self.__add_edge(self.last_request, page)

        self.last_request = page
        self.is_first_request = False

        if page in self.T:
            ## Mark page
            self.marked.add(page)
        else:

            if page in self.H:
                self.H.delete(page)

            # Start a new phase when all pages are marked and a page fault occurs
            # Unmark all the pages
            if len(self.marked) == self.N:
                self.marked.clear()

            if self.T.size() == self.N:

                self.page_probability = self.__calculate_prob(page)

                ## Get the set of unmarked pages
                U = set(self.T.get_data()) - self.marked
                U_list = list(U)
                U_dist = []
                for u in U_list:
                    U_dist.append(self.page_probability[u])

                page_to_evict = random_select_page(U_list, U_dist)

                ## Delete page from cache
                self.T.delete(page_to_evict)

                ## Remove least resent page from history
                if self.H.size() == self.N:
                    hist_lru = self.H.deleteFront()
                    if hist_lru is not None and hist_lru in self.G:
                        self.G.pop(hist_lru, None)

                ## Move discarted page to history
                self.H.add(page_to_evict)

            ## Mark page and add to T
            self.marked.add(page)
            self.T.add(page)

            ## Page fault is True
            page_fault = True

        return page_fault

    def __add_edge(self, u, v):
        if u not in self.G:
            self.G[u] = set()
        if v not in self.G:
            self.G[v] = set()

        self.G[u] = self.G[u] | {v}
        self.G[v] = self.G[v] | {u}

    def get_adj_matrix(self):
        ## Mapping
        node_id = {}
        node_name = {}
        for i, node in enumerate(self.G):
            node_id[node] = i
            node_name[i] = node

        A = np.zeros((len(node_id), len(node_id)))
        for u in self.G:
            adj = list(self.G[u])
            for v in adj:
                if v in self.G:
                    u_id = node_id[u]
                    v_id = node_id[v]
                    A[u_id, v_id] = 1
                    A[v_id, u_id] = 1
                else:
                    self.G[u] = self.G[u] - {v}

        ## Normalize
        for u in range(len(A)):
            degree = np.sum(A[u, :])
            if degree > 0:
                A[u, :] /= degree

        return A, node_id, node_name

    def __calculate_prob(self, init_page):
        A, node_id, node_name = self.get_adj_matrix()

        u = node_id[init_page]
        n = len(A)

        M = Markov(A)
        R = M.random_walk_distribution(u)

        # print('R = ',R)
        P = {}
        for u, p in enumerate(R):
            # print('PR[%s] = %f' % (node_name[u], pr))
            P[node_name[u]] = p

        return P

    ######################################################################################################################################

    def page_label(self, page):
        lab = "%s(%.1f)" % (page, self.page_probability[page]
                            if page in self.page_probability else 0)
        return lab

    def page_color(self, page):
        if page in self.marked:
            return 1  ## Red
        else:
            return 0  # white

    def debug(self):
        X = []
        for u in self.get_data():
            X.append((self.P[u], u))

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.T.get_data()]
class ExpertLearning_v2(page_replacement_algorithm):
    def __init__(self, N):
        self.T = []
        self.N = N
        self.disk = Disk(N)
        self.freq = {}

        ## Training variables
        self.X, self.Y = [], []
        self.reward = []
        self.regret = []

        ## Config variables
        self.batchsize = N
        self.numbatch = 5
        self.discountrate = 0.9
        self.error = 0.5
        self.reduceErrorRate = 0.975

        ## Aux variables
        self.cachebuff = dequecustom()
        self.Xbuff = dequecustom()
        self.Ybuff = dequecustom()
        self.pageHitBuff = dequecustom()
        self.hist = dequecustom()
        self.batchsizeBuff = dequecustom()

        ## Accounting variables
        self.currentPageHits = 0
        self.current = 0
        self.uniquePages = Counter()

        ## Batch action variable
        self.action = [0]

        #self.discount = 0.9
        #self.sampleCount = 0
        #self.trainingSampleSize = 5 * N

        ## start tf
        tf.reset_default_graph()

        self.input = tf.placeholder(shape=[1, self.N], dtype=tf.float32)
        W1 = tf.Variable(tf.random_uniform([self.N, 8], 0, 0.01))
        out1 = tf.sigmoid(tf.matmul(self.input, W1))
        W2 = tf.Variable(tf.random_uniform([8, 2], 0, 0.01))
        self.out = tf.matmul(out1, W2)
        self.predictaction = tf.argmax(self.out)

        self.nextQ = tf.placeholder(shape=[1, 2], dtype=tf.float32)
        loss = tf.reduce_sum(tf.square(self.out - self.nextQ))
        trainer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
        self.updatemodel = trainer.minimize(loss)

        init = tf.global_variables_initializer()
        self.sess = tf.Session()
        self.sess.run(init)

    def get_N(self):
        return self.N

    def __keyWithMinVal(self, d):
        v = list(d.values())
        k = list(d.keys())
        return k[v.index(min(v))]

    def __discountedReward(self, reward):
        discounted_reward = np.zeros(len(reward))
        rsum = 0
        for t in reversed(range(0, len(reward))):
            rsum = self.discount * rsum + reward[t]
            discounted_reward[t] = rsum
        return discounted_reward

    def __getRegret(self):
        cache = set(self.cachebuff.getleft())
        requestSequence = list(self.hist)

        ## Compute distance
        dist = {}
        for j, p in enumerate(requestSequence):
            if p not in dist:
                dist[p] = dequecustom()
            dist[p].append(j)

        discountedregret = 0

        i = 0
        batchid = 0
        optsum = 0
        hitsum = 0
        for hits, sz in zip(self.pageHitBuff, self.batchsizeBuff):
            opthits = 0
            batchid += 1
            for _ in range(0, sz):
                p = requestSequence[i]
                i += 1
                if p in cache:
                    opthits += 1
                else:
                    if len(cache) >= self.N:
                        rem = 'xxxxxxxxxxxxx'
                        for c in cache:
                            if c not in dist or len(dist[c]) == 0:
                                rem = c
                                break
                            if rem not in dist or dist[c].getleft(
                            ) > dist[rem].getleft():
                                rem = c
                        ## Evict from cache
                        cache = cache - {rem}
                    ## Add page to cache
                    cache = cache | {p}
                ## Pop from dist
                dist[p].popleft()

            regret = opthits - hits
            discountedregret = discountedregret + regret * (0.9)**(batchid - 1)
            optsum += opthits
            hitsum += hits
            break

        return discountedregret

    def getState(self):
        x = np.zeros(self.N, np.float32)
        for i, page in enumerate(self.disk):
            x[i] = 1.0 * self.freq[page]
        if np.sum(x) > 0.00001:
            x = x / np.sum(x)
        return x

    ########################################################################################################################################
    ####REQUEST#############################################################################################################################
    ########################################################################################################################################
    def request(self, page):
        page_fault = False

        ############################
        ## Save data for training ##
        ############################
        if len(self.uniquePages) == 0:
            ## Compute regret for the first batch

            if len(self.Xbuff) >= self.numbatch:
                r = self.__getRegret()
                cache = self.cachebuff.popleft()
                s1 = np.array(self.Xbuff.popleft())
                s2 = np.array(self.Xbuff.getleft())
                act = self.Ybuff.popleft()
                hits = self.pageHitBuff.popleft()
                sz = self.batchsizeBuff.popleft()
                for _ in range(0, sz):
                    temp = self.hist.popleft()

                #############################################################################################################################
                ## Train here ###############################################################################################################
                #############################################################################################################################
                allq = self.sess.run(self.out, feed_dict={self.input: s1})
                nextq = self.sess.run(self.out, feed_dict={self.input: s2})
                Qmax = np.max(nextq)
                targetQ = allq
                targetQ[0, act[0]] = r + self.discountrate * Qmax

                _ = self.sess.run(self.updatemodel,
                                  feed_dict={
                                      self.input: s1,
                                      self.nextQ: targetQ
                                  })
                #self.error = self.error * self.reduceErrorRate

            #####################
            ## Choose randomly ##
            #####################
            state = np.array([self.getState()])
            #print(state)
            self.action = self.sess.run(self.predictaction,
                                        feed_dict={self.input: state})

            if np.random.rand() < self.error:
                self.action[0] = 0 if np.random.rand() < 0.5 else 1

            self.cachebuff.append(self.disk.getData())
            self.Xbuff.append(state)
            self.Ybuff.append(self.action)

        #########################
        ## Process page reques ##
        #########################
        if self.disk.inDisk(page):
            self.disk.moveBack(page)
            self.freq[page] += 1
            self.currentPageHits += 1
        else:
            if self.disk.size() == self.N:
                if self.action[0] == 0:
                    ## Remove LRU page
                    lru = self.disk.getIthPage(0)
                    self.disk.delete(lru)
                    del self.freq[lru]
                elif self.action[0] == 1:
                    ## Remove LFU page
                    lfu = self.__keyWithMinVal(self.freq)
                    self.disk.delete(lfu)
                    del self.freq[lfu]
            # Add page to the MRU position
            self.disk.add(page)
            self.freq[page] = 1
            page_fault = True

        #self.uniquePages = self.uniquePages | {page}
        self.uniquePages.update({page: 1})

        ## Store page hits for current batch
        if len(self.uniquePages) == self.N:
            self.pageHitBuff.append(self.currentPageHits)
            self.batchsizeBuff.append(sum(self.uniquePages.values()))
            ## Reset variables
            self.uniquePages.clear()
            self.currentPageHits = 0

        self.hist.append(page)

        return page_fault

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.disk.get_data()]

    def get_list_labels(self):
        return ['L']
Exemple #8
0
class HIT_MARKING(page_replacement_algorithm):
    def __init__(self, N):
        self.T = Disk(N)
        self.H = Disk(N)

        self.N = N
        self.marked = set()
        self.G = Graph()  ## local access graph

        self.is_first_request = True
        self.last_request = -1

        self.hitting_time = {}

        self.fast_mode = True
        self.use_weights = False
        self.weights = {}

    def request(self, page):
        # print('request: ', page)
        page_fault = False

        if not self.is_first_request:
            self.G.increase_edge_weight(self.last_request, page, 1)

        self.last_request = page
        self.is_first_request = False

        if page in self.T:
            ## Mark page
            self.marked.add(page)
        else:

            # Start a new phase when all pages are marked and a page fault occurs
            # Unmark all the pages
            if len(self.marked) == self.N:
                self.marked.clear()

                if self.fast_mode is True:
                    self.hitting_time = self.__calculate_hit_time(page)

            if self.T.size() == self.N:

                if self.fast_mode is False:
                    self.hitting_time = self.__calculate_hit_time(page)

                ## Get the set of unmarked pages
                U = set(self.T.get_data()) - self.marked
                U_list = list(U)
                U_dist = []
                for u in U_list:
                    U_dist.append(self.page_probability[u])

                page_to_evict = random_select_page(U_list, U_dist)

                ## Delete page from cache
                self.T.delete(page_to_evict)

                ## Remove least resent page from history
                if self.H.size() == self.N:
                    hist_lru = self.H.deleteFront()
                    if hist_lru is not None and hist_lru in self.G:
                        self.G.pop(hist_lru, None)

            ## Mark page and add to T
            self.marked.add(page)
            self.T.add(page)

            ## Page fault is True
            page_fault = True

        return page_fault

    def __calculate_hit_time(self, init_page):
        A, node_id, node_name = self.G.get_adj_matrix()

        #######################
        ## Hitting time
        #######################
        # print('R = ',R)

        m = self.G.number_vertices()
        m = self.G.number_edges()

        P = {}
        for u, p in enumerate(R):
            # print('PR[%s] = %f' % (node_name[u], pr))
            P[node_name[u]] = p

        return P

    ######################################################################################################################################

    def page_label(self, page):
        lab = "%s(%.1f)" % (page, self.page_probability[page]
                            if page in self.page_probability else 0)
        return lab

    def page_color(self, page):
        if page in self.marked:
            return 1  ## Red
        else:
            return 0  # white

    def debug(self):
        X = []
        for u in self.get_data():
            X.append((self.P[u], u))

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.T.get_data()]
class ExpertLearning(page_replacement_algorithm):
    def __init__(self, N):
        self.T = []
        self.N = N
        self.disk = Disk(N)
        self.freq = {}

        ## Training variables
        self.X, self.Y = [], []
        self.reward = []
        self.regret = []

        ## Config variables
        self.batchsize = N
        self.numbatch = 5

        ## Aux variables
        self.hist = queue.deque()
        self.Xbuff = queue.deque()
        self.Ybuff = queue.deque()
        self.pageHitBuff = deque()

        self.current = 0
        self.action = 1
        self.currentPageHits = 0

        #self.discount = 0.9
        #self.sampleCount = 0
        #self.trainingSampleSize = 5 * N

    def get_N(self):
        return self.N

    def __keyWithMinVal(self, d):
        v = list(d.values())
        k = list(d.keys())
        return k[v.index(min(v))]

    def __discountedReward(self, reward):
        discounted_reward = np.zeros(len(reward))
        rsum = 0
        for t in reversed(range(0, len(reward))):
            rsum = self.discount * rsum + reward[t]
            discounted_reward[t] = rsum
        return discounted_reward

    def __getRegret(self):
        return 0

    def getState(self):
        x = np.zeros(self.N, np.float32)
        for i, page in enumerate(self.disk):
            x[i] = 1.0 * self.freq[page]
        if np.sum(x) > 0.00001:
            x = x / np.sum(x)
        return x

    def request(self, page):
        page_fault = False

        ############################
        ## Save data for training ##
        ############################
        if self.current == 0:
            ## Compute regret for the first batch
            if len(self.hist) == self.numbatch * self.batchsize:
                reg = self.__getRegret()  ## Regret of first n pages
                x = self.Xbuff.popleft()
                y = self.Ybuff.popleft()
                h = self.pageHitBuff.popleft()

                ## Remove from hist and buffers
                for _ in range(0, self.N):
                    self.hist.get()
            ## Choose randomly
            self.action = 1 if np.random.rand() < 0.5 else 2
            self.Xbuff.append(self.getState())
            self.Ybuff.append(self.action)

        #########################
        ## Process page reques ##
        #########################
        if self.disk.inDisk(page):
            self.disk.moveBack(page)
            self.freq[page] += 1
        else:
            if self.disk.size() == self.N:
                if self.action == 1:
                    ## Remove LRU page
                    lru = self.disk.getIthPage(0)
                    self.disk.delete(lru)
                    del self.freq[lru]
                elif self.action == 2:
                    ## Remove LFU page
                    lfu = self.__keyWithMinVal(self.freq)
                    self.disk.delete(lfu)
                    del self.freq[lfu]

            # Add page to the MRU position
            self.disk.add(page)
            self.freq[page] = 1
            page_fault = True

        ## Increate page hits counter
        self.currentPageHits += 1 * (not page_fault)

        ## Save page hits for current batch
        if self.current + 1 == self.batchsize:
            self.pageHitBuff.append(self.currentPageHits)

        ## Save page in history
        self.hist.put(page)

        ## Increase batch size counter
        self.current = (self.current + 1) % self.batchsize

        return page_fault

    def get_data(self):
        # data = []
        # for i,p,m in enumerate(self.T):
        #     data.append((p,m,i,0))
        # return data
        return [self.disk.get_data()]

    def get_list_labels(self):
        return ['L']