Take one step from current_peer to a neighbor in current_peer_neighbors,
        based on Metropolis-Hastings Random Walk with Delayed Acceptance (MHRWDA).

        The basic idea is to reduce the probability (versus MH alone) that we transition to the previous node.
        We do so using the Metropolis-Hastings Random Walk with Delated Acceptance (MHRWDA) algorithm
        described in Lee, Xu, and Eun in SIGMETRICS 2012.

        Return the next peer.

def random_walk_graph( self, prev_peer, prev_peer_degree, current_peer, current_peer_neighbors, con=None, path=None, peer_table=None ):
        """
        Take one step from current_peer to a neighbor in current_peer_neighbors,
        based on Metropolis-Hastings Random Walk with Delayed Acceptance (MHRWDA).

        The basic idea is to reduce the probability (versus MH alone) that we transition to the previous node.
        We do so using the Metropolis-Hastings Random Walk with Delated Acceptance (MHRWDA) algorithm
        described in Lee, Xu, and Eun in SIGMETRICS 2012.

        Return the next peer.
        """

        if path is None:
            path = self.atlasdb_path

        # the "next" current peer
        ret_current_peer = None
        ret_current_peer_neighbors = None

        error_ret = (None, None)
         
        current_peer_degree = len(current_peer_neighbors)
        if current_peer_degree == 0:
            # nowhere to go 
            log.debug("%s: current peer degree is 0" % (self.my_hostport))
            return error_ret

        next_peer = current_peer_neighbors[ random.randint(0, len(current_peer_neighbors)-1) ]
        next_peer_neighbors = self.get_neighbors( next_peer, con=con, path=path, peer_table=peer_table )
        if next_peer_neighbors is None or len(next_peer_neighbors) == 0:
            # walk failed, or nowhere to go
            # restart the walk
            log.debug("%s: failed to get neighbors of %s" % (self.my_hostport, next_peer))
            return error_ret

        next_peer_degree = len(next_peer_neighbors)

        p = random.random()
        if p <= min(1.0, float(current_peer_degree) / float(next_peer_degree)):
            if prev_peer == next_peer and current_peer_degree > 1:
                # find a different peer
                search = current_peer_neighbors[:]
                if next_peer in search:
                    search.remove(next_peer)

                alt_peer = search[ random.randint(0, len(search)-1) ]
                alt_peer_neighbors = self.get_neighbors( alt_peer, con=con, path=path, peer_table=peer_table )
                if alt_peer_neighbors is None or len(alt_peer_neighbors) == 0:
                    # walk failed, or nowhere to go
                    # restart the walk
                    log.debug("%s: failed to get neighbors of %s" % (self.my_hostport, alt_peer))
                    return error_ret

                alt_peer_degree = len(alt_peer_neighbors)

                q = random.random()
                if q <= min( 1.0, min( 1.0, (float(current_peer_degree) / float(alt_peer_degree))**2 ), max( 1.0, (float(prev_peer_degree) / float(current_peer_degree))**2 ) ):
                    # go to the alt peer instead
                    ret_current_peer = alt_peer
                    ret_current_peer_neighbors = alt_peer_neighbors

                else:
                    # go to next peer
                    ret_current_peer = next_peer
                    ret_current_peer_neighbors = next_peer_neighbors

            else:
                # go to next peer
                ret_current_peer = next_peer
                ret_current_peer_neighbors = next_peer_neighbors
        else:
            # stay here
            ret_current_peer = current_peer
            ret_current_peer_neighbors = self.get_neighbors( current_peer, con=con, path=path, peer_table=peer_table )
            if ret_current_peer_neighbors is None or len(ret_current_peer_neighbors) == 0:
                # nowhere to go
                log.debug("%s: failed to refresh %s" % (self.my_hostport, current_peer))
                return error_ret

        return (ret_current_peer, ret_current_peer_neighbors)