예제 #1
0
def play_recursive_space_cards(deck1: collections.deque,
                               deck2: collections.deque) -> tuple:
    """return the winner and its deck after a recursive space cards game"""
    configurations = set()

    while deck1 and deck2:
        current_config = (tuple(deck1), tuple(deck2))
        if current_config in configurations:
            return 1, deck1
        configurations.add(current_config)

        card1, card2 = deck1.popleft(), deck2.popleft()
        assert card1 != card2
        if card1 <= len(deck1) and card2 <= len(deck2):
            sub_deck1 = collections.deque(itertools.islice(deck1, card1))
            sub_deck2 = collections.deque(itertools.islice(deck2, card2))
            winner, _ = play_recursive_space_cards(sub_deck1, sub_deck2)
        else:
            winner = 1 if card1 > card2 else 2

        if winner == 1:
            deck1.extend((card1, card2))
        else:
            deck2.extend((card2, card1))

    return (1, deck1) if deck1 else (2, deck2)
예제 #2
0
def play_cups(cups: deque, nb_moves):
    for i in range(0, nb_moves):
        #print(f'-- move {i+1} --')
        current_cup = cups[0]

        # print(cups)
        # print(f'current: {current_cup}')

        cups.rotate(-1)

        pickups = [cups.popleft(), cups.popleft(), cups.popleft()]
        destination_cup = get_destination(current_cup, cups)

        # print(f'pick up: {pickups}')
        # print(f'destination: {destination_cup}')

        dest_in = cups.index(destination_cup)

        # push dest to end right end of the queue
        # and add pickups to the right
        cups.rotate(-dest_in - 1)
        cups.extend(pickups)

        # rotate the queue back into initial state shifted once
        cups.rotate(dest_in + 4)
        # print('')

    return cups
예제 #3
0
def bfs(stack: deque):
    while stack:
        current = stack.popleft()
        if current:
            yield current.value
            stack.extend([current.left, current.right])
        yield from bfs(stack)
예제 #4
0
def bfs(to_visit: deque):
    while to_visit:
        current = to_visit.popleft()
        if current:
            yield current.value
            to_visit.extend([current.left, current.right])
        yield from bfs(to_visit)
예제 #5
0
def recursive_combat(first_: deque, second_: deque) -> bool:
    first_states = set()
    second_states = set()
    while len(first_) and len(second_):
        if hash_deque(first_) in first_states or hash_deque(
                second_) in second_states:
            return True

        first_states.add(hash_deque(first_))
        second_states.add(hash_deque(second_))

        first_card = first_.popleft()
        second_card = second_.popleft()

        if len(first_) >= first_card and len(second_) >= second_card:
            first_won = recursive_combat(
                deque(first_[x] for x in range(first_card)),
                deque(second_[x] for x in range(second_card)))
        else:
            first_won = first_card > second_card

        if first_won:
            first_.extend((first_card, second_card))
        else:
            second_.extend((second_card, first_card))

    return len(second_) == 0
예제 #6
0
def random_move_target(queue: collections.deque, opponent_board_view: Board) -> Point:
    """
    Randomly choose an empty square to shoot at when in 'hunt' mode,
    if hit, change to 'target' mode and focus first on neighbor cells.
    """
    # decide moving mode
    if len(queue) == 0:
        mode = 'hunt'
    else:
        mode = 'target'

    # make shot
    if mode == 'hunt':
        empty_xs, empty_ys = np.where(opponent_board_view.shots == NO_SHOT)
        choice = randint(0, len(empty_xs)-1)
        shot = Point(x=empty_xs[choice], y=empty_ys[choice])
    elif mode == 'target':
        shot = queue.popleft()
        while opponent_board_view.shots[shot.x, shot.y] != NO_SHOT:
            if len(queue) > 0:
                shot = queue.popleft()
            else:
                shot = random_move_target(queue, opponent_board_view)

    # add neighbors to queue if the shot is successful
    if opponent_board_view.has_ship[shot.x, shot.y]:
        up = Point(x=shot.x, y=max(shot.y-1, 0))
        down = Point(x=shot.x, y=min(shot.y+1, 9))
        left = Point(x=max(shot.x-1, 0), y=shot.y)
        right = Point(x=min(shot.x+1, 9), y=shot.y)
        neighbors = [up, down, left, right]
        queue.extend(neighbors)

    return shot
예제 #7
0
def play_part_1(deck_1: deque, deck_2: deque):
    while deck_1 and deck_2:
        card_1, card_2 = deck_1.popleft(), deck_2.popleft()

        if card_1 > card_2:
            deck_1.extend((card_1, card_2))
        else:
            deck_2.extend((card_2, card_1))

    return deck_1 if deck_1 else deck_2
예제 #8
0
def play_space_cards(deck1: collections.deque,
                     deck2: collections.deque) -> collections.deque:
    """return the winner's deck after a space cards game"""
    assert len(deck1) == len(deck2)
    while deck1 and deck2:
        card1, card2 = deck1.popleft(), deck2.popleft()
        assert card1 != card2
        if card1 > card2:
            deck1.extend((card1, card2))
        else:
            deck2.extend((card2, card1))

    return deck1 if deck1 else deck2
def breadth_first_search(startnode, goalnode):
    queue = Queue()
    queue.append(startnode)

    nodesseen = set()
    nodesseen.add(startnode)

    while queue:
        node = queue.popleft()

        if node is goalnode:
            return True
        else:
            queue.extend(node for node in node.successors if node not in nodesseen)
            nodesseen.update(node.successors)

    return False
예제 #10
0
 async def comparePanelIds(current_panel_id, current_dialog_count, panel_history: deque):
     logger = logging.getLogger(__name__)
     logger.info("Checking {}...".format(AH_URL))
     new_panel_id = await getPanelID()
     new_dialog_count = await countPanelDialogs(panelIDToURL(new_panel_id))
     if new_panel_id != current_panel_id:
         if new_panel_id not in panel_history:   
             logger.info("New panel ID: {}->{}".format(current_panel_id, new_panel_id))
             logger.info("New panel dialog count: {}".format(new_dialog_count))
             panel_history.extend(new_panel_id)
             await announceNewPanel(panelIDToURL(new_panel_id))
         else:
             logger.info("Repeated panel ID, not announcing: {}".format(new_panel_id))
             logger.info("Panel history: {}".format(panel_history))
     elif new_dialog_count != current_dialog_count:
         logger.info("New dialog count: {}->{}".format(current_dialog_count, new_dialog_count))
         await announceNewPanel(panelIDToURL(current_panel_id))
     return new_panel_id, new_dialog_count
예제 #11
0
def breadth_first_search(startnode, goalnode):
    queue = Queue()
    queue.append(startnode)

    nodesseen = set()
    nodesseen.add(startnode)

    while queue:
        node = queue.popleft()

        if node is goalnode:
            return True
        else:
            queue.extend(node for node in node.successors
                         if node not in nodesseen)
            nodesseen.update(node.successors)

    return False
예제 #12
0
    def bfs(self, board: List[List[str]], bfs_queue: deque, visited: set):

        while len(bfs_queue) > 0:

            cur_pos = bfs_queue.popleft()
            visited.add(cur_pos)

            if self.is_valid(board, cur_pos, visited):
                board[cur_pos[0]][cur_pos[1]] = '-'

            bfs_queue.extend([
                n_pos for n_pos in [(
                    cur_pos[0] + 1,
                    cur_pos[1]), (cur_pos[0] - 1,
                                  cur_pos[1]), (cur_pos[0], cur_pos[1] +
                                                1), (cur_pos[0],
                                                     cur_pos[1] - 1)] if
                self.is_valid(board, n_pos, visited) and n_pos not in visited
            ])
예제 #13
0
파일: BFS_single.py 프로젝트: TienHP/Splat
def breadth_first_search(startnode, goalnode):
    """
    Input:
        startnode: A digraph node
        goalnode: A digraph node
    Output:
        Whether goalnode is reachable from startnode
    """
    queue = Queue()
    queue.append(startnode)
    nodesseen = set()
    nodesseen.add(startnode)
    while queue:
        node = queue.popleft()
        if node is goalnode:
            return True
        else:
            queue.extend(node for node in node.successors if node not in nodesseen)
            nodesseen.update(node.successors)
    return False
예제 #14
0
def play_game(player1: deque, player2: deque) -> int:
    score = 0

    while len(player1) != 0 and len(player2) != 0:
        card1 = player1[0]
        card2 = player2[0]

        if card1 > card2:
            player1.extend([card1, card2])
        elif card2 > card1:
            player2.extend([card2, card1])
        player1.popleft()
        player2.popleft()

    if len(player1) == 0:
        print('Player 2 is winner')
        score = calculate_score(player2)
    elif len(player2) == 0:
        print('Player 1 is winner')
        score = calculate_score(player1)

    return score
예제 #15
0
def extend_state(state: collections.deque) -> Tuple[int, collections.deque]:
    found = False
    ind = 0
    offset = 0
    for i in range(5):
        if state[i] == "#":
            found = True
            ind = i
            break
    if found:
        offset = 5-ind        
        state.extendleft("." for _ in range(offset))
    found = False
    ind = 0
    sl = len(state)
    for i in range(sl - 1, sl - 6, -1):
        if state[i] == "#":
            found = True
            ind = i
            break
    if found:
        state.extend("." for _ in range(5-(sl-ind-1)))
    return offset, state
예제 #16
0
def play_recursive(deck_1: deque, deck_2: deque):
    seen_decks = set()

    while deck_1 and deck_2:
        id = tuple(deck_1), tuple(deck_2)
        if id in seen_decks:
            return True, deck_1
        seen_decks.add(id)

        card_1, card_2 = deck_1.popleft(), deck_2.popleft()
        if len(deck_1) >= card_1 and len(deck_2) >= card_2:
            sub_1, sub_2 = deque(tuple(deck_1)[:card_1]), deque(
                tuple(deck_2)[:card_2])
            you_did_win, _ = play_recursive(sub_1, sub_2)
        else:
            you_did_win = card_1 > card_2

        if you_did_win:
            deck_1.extend((card_1, card_2))
        else:
            deck_2.extend((card_2, card_1))

    return (True, deck_1) if deck_1 else (False, deck_2)
예제 #17
0
def combat(p1_deck: deque, p2_deck: deque, rec=False):
    game_history = set()

    while p1_deck and p2_deck:
        if rec:
            game = tuple(p1_deck) + (0, ) + tuple(p2_deck)
            if game in game_history:
                return 1, p1_deck
            game_history.add(game)

        p1_card, p2_card = p1_deck.popleft(), p2_deck.popleft()

        winner = 1 if p1_card > p2_card else 2

        if rec and len(p1_deck) >= p1_card and len(p2_deck) >= p2_card:
            winner, _ = combat(deque(list(p1_deck)[:p1_card]),
                               deque(list(p2_deck)[:p2_card]), True)

        if winner == 1:
            p1_deck.extend((p1_card, p2_card))
        else:
            p2_deck.extend((p2_card, p1_card))

    return (1, p1_deck) if p1_deck else (2, p2_deck)
예제 #18
0
def play(c1: deque, c2: deque):
    seen = set()
    while len(c1) > 0 and len(c2) > 0:
        p = pack(c1)
        if p in seen:
            return 0, c1
        seen.add(p)
        x = c1.popleft()
        y = c2.popleft()

        if x <= len(c1) and y <= len(c2):
            w, _ = play(deque([c1[i] for i in range(x)], maxlen=51),
                        deque([c2[i] for i in range(y)], maxlen=51))
        else:
            w = x < y

        if w:
            c2.extend([y, x])
        else:
            c1.extend([x, y])
    if len(c1) == 0:
        return 1, c2
    else:
        return 0, c1
예제 #19
0
def play_recursive_combat2(player1: deque, player2: deque):

    seen = set()

    score = 0
    while True:
        p1_hash = ''.join(map(str, player1))
        p2_hash = ''.join(map(str, player2))
        uid = p1_hash + '0' + p2_hash
        if uid in seen:
            winner = 1
            break
        else:
            seen.add(uid)

        c1 = player1.popleft()
        c2 = player2.popleft()

        if len(player1) >= c1 and len(player2) >= c2:
            sub_winner, _ = play_recursive_combat2(
                deque([player1[x] for x in range(c1)]),
                deque([player2[x] for x in range(c2)]))
            if sub_winner == 1:
                player1.extend([c1, c2])
            else:
                player2.extend([c2, c1])
        else:
            if c1 > c2:
                player1.extend([c1, c2])
            else:
                player2.extend([c2, c1])

        if len(player1) == 0:
            winner = 2
            score = calculate_score(player2)
            break
        elif len(player2) == 0:
            winner = 1
            score = calculate_score(player1)
            break

    return winner, score
예제 #20
0
def add_nums_to_deque(source_deque: deque, max_ext: int) -> None:
    if max_ext < 0:
        raise ValueError(f'Invalid max size ({max_ext}) for deque')
    return source_deque.extend([randint(0, max_ext) for _ in range(max_ext)])
예제 #21
0
class Prime(TH.Thread):
    THL = TH.Lock()
    AllThreads = OD([])
    __StopSignal = False
    EarlyStart = True
    EarlyLimit = 4
    
    def __init__(self, Prime=0, RunID=0, JL=[], PN=''):
        if (Prime < 1) or (RunID < 0) or (RunID > Prime):
            raise InvalidPrimeThread  # "neither ID nor JL is correct"
        TH.Thread.__init__(self)
        #
        
        # self.THL.acquire()
        # self.THL.release()
        if True:
            self.__PR = Prime  # current prrime
            self.__ID = RunID  # 0 : dispatcher ---  1..p : worker threads
            #
            tn = self.__MakeName(self.__PR, self.__ID)
            self.setName(tn);                     # easy identifier over all threads
            self.AllThreads.setdefault(tn, [self, self.is_alive(), DT.datetime.now(), None, None, 0])
            #
        if RunID == 0:
            self.__dist = product_Primes(PRIMES)      # distances of start points
            self.__size = length_Jumps(PRIMES)        # length of input JumpList
            self.__Jumpers = DQ([])                   # alternativ. bytearray
            PRIMES.append(self.__PR)                  # set the next step of primes
            self.__maxx = product_Primes(PRIMES)      # frame inside  
            self.__outL = length_Jumps(PRIMES)        # assumed length of target list 
            #
            self.__Strikes = set([])  # numbers to be removed
            # self.__Strikes = set(ListOf_Strikes(JL))  # numbers to be removed
            self.__OutList = DQ([])                   # alternativ. bytearray
            self.AddJumpList(JL)     # get the first jumps and include create strikes
            self.__StartCount = 0    # number of already started subthreads
            self.__FinitCount = 0    # number of already ended subthreads
        if RunID >= 1:
            self.__parent = self.AllThreads[PN][0]
            #
            self.__dist = self.__parent.__dist        # distances of start points
            self.__size = self.__parent.__size        # length of input JumpList
            self.__maxx = self.__parent.__maxx        # frame inside  
            self.__Jumpers = DQ([])                   # alternativ. bytearray
            #
            self.__finit = 1 + (self.__ID * self.__dist)
            self.__begin = self.__finit - self.__dist
        print(self)    
    
    def __str__(self):
        print()
        print(self.getName())
        print('prd:', f'{self.__maxx:>16}', ' |  cnt:', f'{self.__size:>16}', sep='', end='')
        if self.__ID == 0: print(' |  out:', f'{self.__outL:>16}', sep='') 
        else: print()
        print(self.__Jumpers)
        if self.__ID == 0: print(self.__Strikes)
        if self.__ID >= 1: print(self.__parent.getName(), self.__begin, self.__finit)
        # return self.getName()
        return ""

    def __MakeName(self, Prime=0, RunID=0):
        return 'X_' + '{:02}'.format(Prime) + '_' + '{:02}'.format(RunID)
        
    def __MakeStrikes(self):
        if (self.__ID != 0) or (len(self.__Jumpers) == 0):
            return
        if len(self.__Jumpers) < min(self.EarlyLimit, self.__size):
            return
        # print('MS:', self.__Jumpers)
        self.THL.acquire()
        self.__Strikes = set(ListOf_Strikes(self.__Jumpers))
        self.THL.release()
    
    def __InitWorkers(self):
        if (self.__ID != 0):
            return
        for i in range(self.__PR):
            Prime(self.__PR, i+1, PN=self.getName())
            if i > 0: continue
            if self.EarlyStart and (i+1 == 1):
                self.__StartWorker(self.__PR, i+1)
                print('ExtraStart')

    def __StartWorker(self, PR=0, ID=0):
        tn = self.__MakeName(PR, ID)
        print('try to start: ', tn)
        T = None
        self.__StartCount += 1
        try:
            T = self.AllThreads[tn][0]
            print(tn, T)
            print(tn, 'alive1', T.is_alive())
            T.start()
            # print(tn, 'ident:', T.T.ident)
            print(tn, 'alive2', T.is_alive())
            delay(2000)
            print(tn, 'alive3', T.is_alive())
            # if T.ident() == 0:
            # if T.ident() > 0:
            T.start()
            print(tn, 'alive4', T.is_alive())
        except:
            print('oops', tn)
            pass

    def AddJumpList(self, JL=[]):
        if (self.__ID != 0):
            return
        if len(self.__Jumpers) + len(JL) > self.__size:
            return
        self.THL.acquire()
        self.__Jumpers.extend(JL)
        self.THL.release()
        # print('JL:', self.__Jumpers)
        if len(self.__Jumpers) >= min(self.EarlyLimit, self.__size):
            self.__MakeStrikes()  # input jumpers complete we can create all strikers

    def EmergencyStop():
        Prime.__StopSignal = True
        delay(1500)
        Prime.THL.acquire()
        Z = [T for T in TH.enumerate() if T.getName().find('X_') == 0]
        Prime.THL.release()
        if len(Z) > 0:
            print('>>> stopping threads: ', end='')
            while len(Z) > 0:
                T = Z.pop()
                print('\t', T.getName(), end='')
                # T._stop()
            else:
                print('\t <<<')

    def run(self):
        X = self.AllThreads[self.getName()]
        X[3] = DT.datetime.now()
        #
        print('RUN', end=': ')
        if self.__ID == 0:
            print('dispatch', self.__PR, self.__ID)
            if len(self.__Jumpers) > min(self.EarlyLimit, self.__size):
                self.__InitWorkers()  # create all sub threads to compute next jump list in partitions
            while self.__StartCount < self.__PR:
                if len(self.__Jumpers) >= self.__size:
                    for i in range(self.__PR):
                        self.__StartWorker(self.__PR, ID=i+1)
                delay(1000)
        elif self.__ID <= self.__PR:
            print('compute', self.__PR, self.__ID)
            delay(1000)
        else:
            print('failure', self.__PR, self.__ID)
        #
        X[4] = DT.datetime.now()
예제 #22
0
class PrimeDispatch(PrimeBase):
    """
    holds the current prime and some common values for all worker child threads
    collects after running childs the new jumper list
    """

    #
    def __init__(self, Prime=0, RunID=0, JL=[]):
        if (Prime < 1) or (Prime > MAXPRIME) or (RunID != 0):
            raise InvalidPrimeThread  # out of range
        PrimeBase.__init__(self, Prime, RunID)
        PrimeBase.THL.acquire()
        if True:  # only for a good block visibility
            # PRIMES has still in values
            self._dist = product_Primes(PRIMES)  # distances of start points
            self._size = length_Jumps(PRIMES)  # length of input JumpList
            self._Jumpers = DQ([])  # alternatively use a bytearray
            self._Strikes = set([])  # numbers to be removed
            PRIMES.append(Prime)  # set the next step of primes
            print(PRIMES, flush=True)
            # PRIMES changed for out values
            self.__maxx = product_Primes(PRIMES)  # size of frame inside
            self.__outL = length_Jumps(PRIMES)  # assumed length of target list
            self._OutList = OD([])
            # self.__OutList = DQ([])               # alternatively use a bytearray
            #
        PrimeBase.THL.release()
        if len(JL) > 0:
            self.AddJumpList(
                JL)  # get the first jumps and include create strikes

    #
    def __str__(self):
        t = PrimeBase.__str__(self)
        print(t, flush=True)
        print(self._Jumpers, flush=True)
        print(self._Strikes, flush=True)
        return t

    #
    def __MakeStrikes(self):
        if (len(self._Jumpers) == 0):
            return
        if len(self._Jumpers) < min(PrimeBase.EarlyLimit, self._size):
            return
        # print('MS:', self._Jumpers, flush=True)
        self.THL.acquire()
        self._Strikes = set(ListOf_Strikes(self._Jumpers))
        self.THL.release()

    #
    def AddJumpList(self, JL=[]):
        if len(JL) == 0: return
        if len(self._Jumpers) + len(JL) > self._size:
            return
        if True:
            self.THL.acquire()
            self._Jumpers.extend(JL)
            self.THL.release()
        if len(self._Jumpers) >= self._size:
            self.__MakeStrikes(
            )  # input jumpers complete we can create all strikers
        if len(self._Jumpers) <= 48:
            print('JL:', self._PR, self._ID, list(self._Jumpers), flush=True)
        else:
            print('JL:',
                  self._PR,
                  self._ID,
                  list(self._Jumpers)[:21],
                  '...',
                  list(self._Jumpers)[-21:],
                  flush=True)

    #
    def __InitWorkers(self):
        for i in range(self._PR):
            if PrimeBase._StopSignal: break
            tn = self._MakeName(self._PR, i + 1)
            self._OutList.setdefault(tn, [])
            PrimeWorker(self._PR, i + 1, self)

    #
    def __StartWorker(self, PR=0, ID=0):
        tn = self._MakeName(PR, ID)
        try:
            X = PrimeBase.AllThreads[tn]
            T = X.TObject
            if T.ident is None: T.start()
        except:
            print('problems starting thread: ', tn, flush=True)

    #
    def run(self):
        X = self.AllThreads[self.getName()]
        X.StartTime = DT.datetime.now()
        print('Thread started:', self._PR, flush=True)
        #
        while len(self._Jumpers) < min(PrimeBase.EarlyLimit, self._size):
            if PrimeBase._StopSignal: break
            print(self.getName(),
                  'wait for jumpers before init childs',
                  flush=True)
            delay(self._PR)
            X.PauseCnt += 1
        self.__InitWorkers(
        )  # create all sub threads to compute next jump list in partitions
        delay(10 * self._PR)
        while len(self._Jumpers) < self._size:
            if PrimeBase._StopSignal: break
            print(self.getName(),
                  'wait for jumpers after init childs',
                  flush=True)
            delay(self._PR)
            X.PauseCnt += 1
        for i in range(self._PR):
            if PrimeBase._StopSignal: break
            # print(self.getName(), 'start workers b', self._PR, i+1, flush=True)
            self.__StartWorker(self._PR, ID=i + 1)
            delay(3)
        pNextJumps = 1
        pN = None
        np = 0
        zBreak = False
        # now let it run and wait for results
        while not zBreak:
            if PrimeBase._StopSignal: break
            zBreak = True
            PrimeBase.THL.acquire()
            print('get thread list', flush=True)
            ZZ = [
                Z for Z in PrimeBase.AllThreads.values()
                if Z.Prime == self._PR and Z.RunID > 0
            ]
            PrimeBase.THL.release()
            for Z in ZZ:
                zBreak &= Z.I_AmReady
                print('$$: ',
                      Z.Prime,
                      Z.RunID,
                      Z.I_AmReady,
                      Z.WhereItIs,
                      flush=True)
            # Korrektur für kleine Primzahlen, kurze Jumplisten zusammenziehen
            if zBreak and self._size < PrimeBase.EarlyLimit:
                tn1 = self._MakeName(self._PR, 1)
                for i in range(2, self._PR + 1):
                    tni = self._MakeName(self._PR, i)
                    self._OutList[tn1].extend(self._OutList[tni])
                    self._OutList[tni].clear()
            # Startvorbereitungen für nächste Primzahl vorbereiten
            tn = self._MakeName(self._PR, 1)
            if len(self._OutList[tn]) > 0: np = nextPrime(self._OutList[tn])
            if (pN is None) and (1 < np <= MAXPRIME):
                print('create new thread: ', np, flush=True)
                pN = PrimeDispatch(np, 0)

            if pN:
                for Z in ZZ:
                    if (Z.RunID == pNextJumps) and Z.I_AmReady:
                        tn = self._MakeName(Z.Prime, Z.RunID)
                        print('working ...',
                              self._PR,
                              pNextJumps,
                              '-->',
                              np,
                              flush=True)
                        pN.AddJumpList(self._OutList[tn])
                        pNextJumps += 1

            print('just before start ...done:',
                  self._PR,
                  pNextJumps - 1,
                  '-->',
                  np,
                  flush=True)
            if (pN is not None) and (pNextJumps > self._PR):
                print('start new thread: ', np, flush=True)
                pN.start()

        while True:
            if PrimeBase._StopSignal: break
            zi = 0
            za = 0
            zz = 0
            for Z in PrimeBase.AllThreads.values():
                if Z.Prime == self._PR and Z.RunID > 0:
                    if Z.InitTime is not None: zi += 1
                    if Z.StartTime is not None: za += 1
                    if Z.ReadyTime is not None: zz += 1
            if zi == 0: break
            if za == zz: break
            delay(10 * self._PR)
            X.PauseCnt += 1
        #
        X.FinitTime = DT.datetime.now()
        print(self.getName(), 'run finished', flush=True)
예제 #23
0
def main(args):
    env = GridWorld.load(args.env)

    dev = torch.device(
        "cuda" if args.use_cuda and torch.cuda.is_available() else "cpu")
    q_net = build_MLP(2, *args.hidden_dims, 4)
    target_net = build_MLP(2, *args.hidden_dims, 4)
    target_net.load_state_dict(q_net.state_dict())
    q_net.to(dev)
    target_net.to(dev)

    optim = torch.optim.SGD(q_net.parameters(), lr=args.base_lr)
    if args.lr_decay is not None:
        lr_sched = torch.optim.lr_scheduler.StepLR(optim, args.lr_step,
                                                   args.lr_decay)
    epsilon = args.base_epsilon

    memory = ReplayMemory(maxlen=args.mem_size)

    avg_cumul = None
    avg_success = None
    avg_loss = None
    AVG_R = 0.05
    stats = []
    try:
        with tqdm.trange(args.max_iter) as progress:
            for it in progress:
                trajectory, cumul, success = sample_trajectory(
                    env, lambda z: epsilon_greedy(z, q_net, epsilon),
                    args.max_t)
                memory.extend(trajectory)

                loss = 0
                for b, batch in enumerate(
                        sample_batch(memory, args.batch_size, args.batch_count,
                                     dev)):
                    loss += update_weights(q_net, target_net, optim,
                                           *batch[:-1], args.discount)
                if b > 0:
                    loss /= b

                avg_cumul = cumul if avg_cumul is None else (
                    1 - AVG_R) * avg_cumul + AVG_R * cumul
                avg_success = success if avg_success is None else (
                    1 - AVG_R) * avg_success + AVG_R * success
                avg_loss = loss if avg_loss is None else (
                    1 - AVG_R) * avg_loss + AVG_R * loss
                lr = optim.param_groups[0]["lr"]
                progress.set_postfix(cumul=avg_cumul,
                                     success=avg_success,
                                     loss=avg_loss,
                                     lr=lr,
                                     eps=epsilon)
                stats.append(
                    (it, avg_cumul, avg_success, avg_loss, lr, epsilon))

                if it % args.freeze_period == args.freeze_period - 1:
                    target_net.load_state_dict(q_net.state_dict())
                if args.lr_decay is not None:
                    lr_sched.step()
                if args.eps_decay is None:
                    epsilon = (args.base_epsilon - args.min_epsilon) * (
                        1 - it / args.max_iter) + args.min_epsilon
                elif it % args.eps_step == args.eps_step - 1:
                    epsilon = max(epsilon * args.eps_decay, args.min_epsilon)
    except KeyboardInterrupt:
        pass

    os.makedirs(args.output_dir, exist_ok=True)
    with open(os.path.join(args.output_dir, "training_args.json"), 'w') as f:
        json.dump(vars(args), f, indent=4)
    torch.save(q_net.state_dict(),
               os.path.join(args.output_dir, "trained_mlp_{}.pkl".format(it)))
    with open(os.path.join(args.output_dir, "training_stats.csv"), 'w') as f:
        for it_stat in stats:
            f.write(', '.join(str(s) for s in it_stat))
            f.write('\n')