Esempio n. 1
0
        out_species.writerow(out_row_species)

    file_species.close()

    stop_sim = datetime.now()
    elapsed_sim = stop_sim - start_sim
    print 'time for simulation', elapsed_sim

    #ecosystem.draw_species_distribution()

    #layout = nx.graphviz_layout(net, prog='dot', args='-Gnodesep=.07, -Granksep=.1, -Grankdir=BT')
    layout = nx.circular_layout(net)

    #fig = figure()
    #network_plot = fig.add_subplot(111)
    #nx.draw_networkx(net, layout, ax=network_plot)

    print 'S original =', net.order(), 'L original =', net.size(
    ), 'C original =', net.connectance()
#
#    net_final = ecosystem.realised_net.copy()
#    layout2 = nx.circular_layout(net_final)
#
#    fig2 = figure()
#    network_plot2 = fig2.add_subplot(111)
#    nx.draw_networkx(net_final, layout2, ax=network_plot2)
#
#    print 'S realised =', net_final.order(), 'L realised =', net_final.size(), 'C realised =', net_final.connectance()

#show()
class NetworkCreator():
    '''
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.rnd = Random()
        self.rnd_uniform = uniform()
        self.net = Network()
    
#        self.invaders = []
    
    def reset_state(self):
        self.rnd = Random()
        self.rnd_uniform = uniform()
        self.net.clear()
    
    def create_niche_model_network(self, S, C, prob=False):
        '''
        prob = False; whether to create the network following the probabilistic niche model
        Niche model
        
        This is an implementation of the niche model
        '''
        ns = self.rnd_uniform.rvs(size=S+POSSIBLE_INVADERS)
        bet = (1/(2*C)) - 1
        self.beta_dist = beta(1,bet)
        
        producers = int(math.floor(S*PRIMARY_PRODS))
        current_producers = 0
        
        herbivores = int(math.floor(S*HERBIVORY))
        current_herbivores = 0 
        
        predators = int(math.floor(S*TOP_PREDATORS))
        current_predators = 0    

	#basal_to_top_links = 1  ## New constraint that this must be zero!

        while self.net.size() == 0 or not nx.is_connected(self.net.to_undirected()) or current_producers < producers or current_herbivores < herbivores or current_predators < predators: #or max(self.net.get_shortest_chain_length().values()) < 3:
            self.net.clear()
#            self.invaders = []
            
            basal = None
            smallest_n = None
            
            #here we obtain the fundamental niche values for each one of the species in the network
            # n, c, r
            for i in xrange(1,S+1):
                self.net.add_node(i)
                self.net.node[i]['n'] = float(ns[i-1]) #self.rnd_uniform.rvs()
                self.net.node[i]['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
                self.net.node[i]['c'] = self.rnd.uniform((self.net.node[i]['r']/2), min(self.net.node[i]['n'], (1-(self.net.node[i]['r']/2))))
                #the original value of c (commented bit) as originally presented in the Nature 2000 paper
                #was changed after reading the niche model specification presented in the JAE 2008 paper
                #the new specification ensures that the r of all the species always lie within the niche interval [0,1]
                #self.net.node[i]['c'] = self.rnd.uniform(self.net.node[i]['r']/2, self.net.node[i]['n'])
                self.net.node[i]['invader'] = False
                
                if smallest_n == None or self.net.node[i]['n'] < smallest_n:
                    smallest_n = self.net.node[i]['n']
                    basal = i
            
            #if INVASION:
#            for i in xrange(S+1, (S+1)+(POSSIBLE_INVADERS)):
##                invader = dict()
##                invader['n'] = self.rnd_uniform.rvs()
##                invader['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
##                invader['c'] = self.rnd.uniform(self.net.node[i]['r']/2, self.net.node[i]['n'])
##                invader['invader'] = True
#                
#                self.net.add_node(i)
#                self.net.node[i]['n'] = float(ns[i-1]) #self.rnd_uniform.rvs()
#                self.net.node[i]['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
#                self.net.node[i]['c'] = self.rnd.uniform((self.net.node[i]['r']/2), min(self.net.node[i]['n'], (1-(self.net.node[i]['r']/2))))
#                self.net.node[i]['invader'] = False
                
#                self.invaders.append(invader)
                          
            self.net.node[basal]['r'] = 0.0    
            self._create_links_based_on_fundamental_niche()


            tls = self.net.get_trophic_levels()
	    # replacement of links between trophic levels 0 and 3 (does not conform to niches):
            top, top_preds = self.net.top_predators()
            basal, basal_sps = self.net.basal()
	    #basal_to_top_links = 0
	    to_replace = []
            for u,v in self.net.edges():
                if u in basal_sps and v in top_preds and tls[v] == 3:
                    #basal_to_top_links += 1
		    self.net.remove_edge(u,v)
		    to_replace.append((u,v))
       
	    for pair in to_replace:
		new_u = pair[1]
		while new_u in basal_sps or new_u==pair[1]:
			new_u = np.random.randint(1,61)     # species indexing starts at 1
		self.net.add_edge(new_u, pair[1]) 
            
	    # calculations to check trophic constraints:
            current_herbivores = 0
            current_producers = 0
            current_predators = 0
            for k in tls.keys():
                if tls[k] == 1:
                    current_herbivores += 1 
                elif tls[k] == 0:
                    current_producers += 1
                elif tls[k] == 3:
                    current_predators += 1

        print("replaced %d links" %(len(to_replace)))
        return self.net
            
    def _create_links_based_on_fundamental_niche(self, nodes_to_link=None):
        #based on the fundamental niche values obtained above we construct the network by adding
        #the corresponding links according to the species' niche and feeding range
        
        if nodes_to_link == None:
            nodes_to_link = set(self.net.nodes())
        
        for i in self.net.nodes():
            if self.net.node[i]['r'] == 0.0:
                continue
            
            r_lower_bound = self.net.node[i]['c'] - (self.net.node[i]['r']/2)
            r_upper_bound = self.net.node[i]['c'] + (self.net.node[i]['r']/2) 
            for j in self.net.nodes():
                if i not in nodes_to_link and j not in nodes_to_link:
                    continue
                
                if self.net.node[j]['n'] >= r_lower_bound and self.net.node[j]['n'] <= r_upper_bound:  
                    self.net.add_edge(j,i)
        
        #for disconnected or duplicated nodes
        disc_nodes = set()        
        self_loops = set(self.net.selfloop_edges())
        
        for i in nodes_to_link:
            disconnected = False
            
            if self.net.degree(i) == 0:
                disconnected = True
            elif self.net.in_degree(i) == 1 and (i,i) in self_loops:
#                print 'producer with selfloop'
                if self.net.out_degree(i) > 1:
                    self.net.remove_edge(i,i)
                else:
                    disconnected = True
                    attrs = self.net.node[i]
                    self.net.remove_node(i)
                    self.net.add_node(i, attr_dict=attrs)
            else:
                i_succs = set(self.net.successors(i))
                i_predecs = set(self.net.predecessors(i))
                for j in self.net.nodes():
                    j_succs = self.net.successors(j)
                    j_predecs = self.net.predecessors(j)
                    
                    if i_succs == j_succs and i_predecs == j_predecs:
                        disconnected = True
                        attrs = self.net.node[i]
                        self.net.remove_node(i)
                        self.net.add_node(i, attr_dict=attrs)
                        print 'duplicated node'
                        break
                    
            #we reassign the fundamental niche values to nodes that are disconnected or duplicated        
            if disconnected:
                self.net.node[i]['n'] = self.rnd_uniform.rvs()
                self.net.node[i]['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
                self.net.node[i]['c'] = self.rnd.uniform(self.net.node[i]['r']/2, self.net.node[i]['n'])
                disc_nodes.add(i)
                
        
        if len(disc_nodes) > 0:
            self._create_links_based_on_fundamental_niche(disc_nodes)
        
        return
Esempio n. 3
0
class NetworkCreator():
    '''
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.rnd = Random()
        self.rnd_uniform = uniform()
        self.net = Network()

#        self.invaders = []

    def reset_state(self):
        self.rnd = Random()
        self.rnd_uniform = uniform()
        self.net.clear()

    def create_niche_model_network(self, S, C, prob=False):
        '''
        prob = False; whether to create the network following the probabilistic niche model
        Niche model
        
        This is an implementation of the niche model
        '''
        ns = self.rnd_uniform.rvs(size=S + POSSIBLE_INVADERS)
        bet = (1 / (2 * C)) - 1
        self.beta_dist = beta(1, bet)

        producers = int(math.floor(S * PRIMARY_PRODS))
        current_producers = 0

        herbivores = int(math.floor(S * HERBIVORY))
        current_herbivores = 0

        predators = int(math.floor(S * TOP_PREDATORS))
        current_predators = 0
        while self.net.size() == 0 or not nx.is_connected(
                self.net.to_undirected()
        ) or current_herbivores < herbivores or current_producers < producers or current_predators < predators:  #or max(self.net.get_shortest_chain_length().values()) < 3:
            self.net.clear()
            #           self.invaders = []

            basal = None
            smallest_n = None

            #here we obtain the fundamental niche values for each one of the species in the network
            # n, c, r
            for i in range(1, S + 1):
                self.net.add_node(i)
                self.net.nodes[i]['n'] = float(ns[i -
                                                  1])  #self.rnd_uniform.rvs()
                self.net.nodes[i]['r'] = self.beta_dist.rvs(
                ) * self.net.nodes[i]['n']
                self.net.nodes[i]['c'] = self.rnd.uniform(
                    (self.net.nodes[i]['r'] / 2),
                    min(self.net.nodes[i]['n'],
                        (1 - (self.net.nodes[i]['r'] / 2))))
                #the original value of c (commented bit) as originally presented in the Nature 2000 paper
                #was changed after reading the niche model specification presented in the JAE 2008 paper
                #the new specification ensures that the r of all the species always lie within the niche interval [0,1]
                #self.net.node[i]['c'] = self.rnd.uniform(self.net.node[i]['r']/2, self.net.node[i]['n'])
                self.net.nodes[i]['invader'] = False

                if smallest_n == None or self.net.nodes[i]['n'] < smallest_n:
                    smallest_n = self.net.nodes[i]['n']
                    basal = i

            #if INVASION:


#            for i in xrange(S+1, (S+1)+(POSSIBLE_INVADERS)):
##                invader = dict()
##                invader['n'] = self.rnd_uniform.rvs()
##                invader['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
##                invader['c'] = self.rnd.uniform(self.net.node[i]['r']/2, self.net.node[i]['n'])
##                invader['invader'] = True
#
#                self.net.add_node(i)
#                self.net.node[i]['n'] = float(ns[i-1]) #self.rnd_uniform.rvs()
#                self.net.node[i]['r'] = self.beta_dist.rvs() * self.net.node[i]['n']
#                self.net.node[i]['c'] = self.rnd.uniform((self.net.node[i]['r']/2), min(self.net.node[i]['n'], (1-(self.net.node[i]['r']/2))))
#                self.net.node[i]['invader'] = False

#                self.invaders.append(invader)

            self.net.nodes[basal]['r'] = 0.0
            self._create_links_based_on_fundamental_niche()

            current_herbivores = 0
            current_producers = 0
            current_predators = 0
            tls = self.net.get_trophic_levels()
            for k in tls.keys():
                if tls[k] == 1:
                    current_herbivores += 1
                elif tls[k] == 0:
                    current_producers += 1
                elif tls[k] == 3:
                    current_predators += 1

        return self.net

    def _create_links_based_on_fundamental_niche(self, nodes_to_link=None):
        #based on the fundamental niche values obtained above we construct the network by adding
        #the corresponding links according to the species' niche and feeding range

        if nodes_to_link == None:
            nodes_to_link = set(self.net.nodes())

        for i in self.net.nodes():
            if self.net.nodes[i]['r'] == 0.0:
                continue

            r_lower_bound = self.net.nodes[i]['c'] - (self.net.nodes[i]['r'] /
                                                      2)
            r_upper_bound = self.net.nodes[i]['c'] + (self.net.nodes[i]['r'] /
                                                      2)
            for j in self.net.nodes():
                if i not in nodes_to_link and j not in nodes_to_link:
                    continue

                if self.net.nodes[j]['n'] >= r_lower_bound and self.net.nodes[
                        j]['n'] <= r_upper_bound:
                    self.net.add_edge(j, i)

        #for disconnected or duplicated nodes
        disc_nodes = set()
        self_loops = set(nx.selfloop_edges(self.net))

        for i in nodes_to_link:
            disconnected = False

            if self.net.degree(i) == 0:
                disconnected = True
            elif self.net.in_degree(i) == 1 and (i, i) in self_loops:
                #                print 'producer with selfloop'
                if self.net.out_degree(i) > 1:
                    self.net.remove_edge(i, i)
                else:
                    disconnected = True
                    attrs = self.net.nodes[i]
                    self.net.remove_node(i)
                    self.net.add_node(i, attr_dict=attrs)
            else:
                i_succs = set(self.net.successors(i))
                i_predecs = set(self.net.predecessors(i))
                for j in self.net.nodes():
                    j_succs = self.net.successors(j)
                    j_predecs = self.net.predecessors(j)

                    if i_succs == j_succs and i_predecs == j_predecs:
                        disconnected = True
                        attrs = self.net.nodes[i]
                        self.net.remove_node(i)
                        self.net.add_node(i, attr_dict=attrs)
                        print('duplicated node')
                        break

            #we reassign the fundamental niche values to nodes that are disconnected or duplicated
            if disconnected:
                self.net.nodes[i]['n'] = self.rnd_uniform.rvs()
                self.net.nodes[i]['r'] = self.beta_dist.rvs(
                ) * self.net.nodes[i]['n']
                self.net.nodes[i]['c'] = self.rnd.uniform(
                    self.net.nodes[i]['r'] / 2, self.net.nodes[i]['n'])
                disc_nodes.add(i)

        if len(disc_nodes) > 0:
            self._create_links_based_on_fundamental_niche(disc_nodes)

        return
        tps = cumulative_sps_stats[sp]['tps']
        if len(tps) == 0:
            mean_tps = 'N/A'
            sd_tps = 'N/A'
        else:
            mean_tps = sum(tps) / len(tps)
            sd_tps = 0.0
            for n in tps:
                sd_tps += (n - mean_tps)**2

            sd_tps = math.sqrt(sd_tps / len(tps))

        out_row_species['mean_tp'] = mean_tps
        out_row_species['tp_sd'] = sd_tps

        out_row_species['individuals'] = series_counts[ITERATIONS][sp]
        out_row_species['immigrants'] = cumulative_sps_stats[sp]['immigrants']
        out_row_species['born'] = cumulative_sps_stats[sp]['born']
        out_row_species['dead'] = cumulative_sps_stats[sp]['dead']

        out_species.writerow(out_row_species)

    file_species.close()

    stop_sim = datetime.now()
    elapsed_sim = stop_sim - start_sim
    print('time for simulation', elapsed_sim)

    print('S original =', net.order(), 'L original =', net.size(),
          'C original =', net.connectance())