谢林分离问题的 Python 代码错误

问题描述 投票:0回答:1

我有一个问题,我应该使用 pythong 对谢林分离问题进行建模。我已经坚持了很长一段时间,但我认为我的问题是我的邻居没有被正确地从一个不快乐的代理人换成一个空代理人。

**问题范围:** 我们有一个包含 0、1 和 2 的矩阵。 os代表空房子,1s代表一种种族,2s代表另一种种族。如果一个种族不满意他们的邻居(由 self.par 定义)与他们相似,那么他们就会成为不快乐的代理人。这些不开心的特工需要调换到空房子里。这需要在多个时间步长上重复,并且随着人们变得“快乐”

,指标(即下面代码定义的 frac_mean)应该减少

但是,我的问题是 frac mean 指标没有显示出一致的下降模式。

** 我尝试过的事情:** 我尝试的主要事情不是在原始 self.array 中进行交换,而是复制它并在其上进行所有交换,然后将其等同于代码倒数第二行所见的原始 self 数组。

任何帮助将不胜感激:

class Schelling():
    kernel = [[1,1,1],[1,0,1],[1,1,1]]
    #par = 0.3
    
    def __init__(self, n, par=0.3):
        self.par=par
        probs = [0.1, 0.45, 0.45]
        choices = [0, 1, 2]
        self.array = np.random.choice(choices, (n, n), p=probs)

    def count_neighbours(self):
        a = self.array
        
        empty = a == 0
        red = a == 1
        blue = a == 2

        num_red = correlate2d(red, self.kernel, mode='same', boundary='wrap')
        num_blue = correlate2d(blue, self.kernel, mode='same', boundary='wrap')
        num_neighbours = num_red + num_blue

        frac_red = num_red / num_neighbours
        frac_blue = num_blue / num_neighbours

        frac_red[num_neighbours == 0] = 0
        frac_blue[num_neighbours == 0] = 0

        # Nice way to do a vector if-else application
        frac_same = np.where(red, frac_red, frac_blue)

        # Because only if-else, empty will have frac_blue, so we need to correct this
        frac_same[empty] = np.nan

        return empty, frac_red, frac_blue, frac_same, a
    
    def step(self):
        empty, frac_red, frac_blue, frac_same, count_neighbours_list = self.count_neighbours()
        metric=np.nanmean(frac_same)
        unhappy_address = list(zip(*np.array(np.nonzero(frac_same < self.par))))
        np.random.shuffle(unhappy_address)
        empty_address = list(zip(*np.array(np.nonzero(empty))))

        
        # Perform swaps until no more swaps are possible
        unhappy_copy=unhappy_address.copy()
        empty_copy=empty_address.copy()
        
        ind=len(unhappy_copy)
        
        #ind=min(len(unhappy_address), len(empty_address))
        for i in range(ind):
            #adding a check: 
            #add in a break: for the value of i if its greater than len-1 of empty_address, then break  
            if i == len(empty_address):
                
                break
                
            else:
            
                unhappy_tup_req=unhappy_copy[i]
                emp_tup_req=empty_copy[i]
                
                #count_neighbours_list[emp_tup_req]=count_neighbours_list[unhappy_tup_req]
                #count_neighbours_list[unhappy_tup_req]==0
                
                count_neighbours_list[emp_tup_req], count_neighbours_list[unhappy_tup_req] = count_neighbours_list[unhappy_tup_req], count_neighbours_list[emp_tup_req]

            
        self.array= count_neighbours_list
                

        return unhappy_address, empty_address, count_neighbours_list, metric


python algorithm sorting probability agent-based-modeling
1个回答
0
投票

这里有一些你可以尝试的东西:

  1. 确保您正确识别不满意的座席。您可以通过遍历数组并检查每个代理的邻居分数是否小于相似性阈值来完成此操作。
  2. 一旦你确定了不开心的代理人,你需要找一个空房子让他们搬进去。您可以通过遍历数组并检查是否有任何房屋是空的来完成此操作。
  3. 一旦您为不满意的代理人找到空房子,您需要将代理人与空房子的居住者交换。您可以使用
    swap
    功能来做到这一点。
  4. 一旦您将代理与空房子的居住者交换,您需要更新数组以反映更改。您可以使用
    update
    功能来做到这一点。
  5. 重复步骤 1-4 直到不再发现不满意的代理。

以下是如何在 Python 中实现上述步骤的示例:

def schelling_segregation(array, similarity_threshold):
  """
  This function implements the Schelling segregation model.

  Args:
    array: A 2D array representing the city.
    similarity_threshold: The threshold that is used to determine if an agent is happy.

  Returns:
    A 2D array representing the final state of the city.
  """

  # Initialize the list of unhappy agents.
  unhappy_agents = []

  # Loop through the array and identify the unhappy agents.
  for i in range(len(array)):
    for j in range(len(array[0])):
      if array[i][j] != 0:
        fraction_of_neighbors = 0
        for neighbor in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
          if 0 <= neighbor[0] < len(array) and 0 <= neighbor[1] < len(array[0]):
            if array[neighbor[0]][neighbor[1]] == array[i][j]:
              fraction_of_neighbors += 1

        if fraction_of_neighbors < similarity_threshold:
          unhappy_agents.append((i, j))

  # Loop through the list of unhappy agents and swap them with an empty house.
  for i, j in unhappy_agents:
    while True:
      empty_house = None
      for neighbor in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
        if 0 <= neighbor[0] < len(array) and 0 <= neighbor[1] < len(array[0]):
          if array[neighbor[0]][neighbor[1]] == 0:
            empty_house = neighbor
            break

      if empty_house is not None:
        array[i][j], array[empty_house[0]][empty_house[1]] = array[empty_house[0]][empty_house[1]], array[i][j]
        break

  return array

希望对您有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.