【问题标题】:Recursion - Creating a matrix to paint a PPM file递归 - 创建一个矩阵来绘制 PPM 文件
【发布时间】:2023-01-18 16:11:11
【问题描述】:

我们有一个代表图像的 .ppm 文件,它被转换成矩阵形式。像这样:

208 21  139 96  38  169 0   172 123 115 172 154 0   227 153 29  234 109 222 39
5   241 176 62  133 69  0   152 145 154 99  93  0   74  85  47  241 23  207 45
25  92  229 196 163 139 0   189 76  0   0   220 0   2   152 0   79  44  249 203
5   8   75  228 108 125 0   129 0   39  0   18  0   144 30  0   0   0   172 54
222 3   25  196 240 0   0   1   0   11  0   226 0   202 20  203 235 169 0   93
238 184 0   0   0   0   249 123 0   178 0   252 0   91  152 49  119 200 0   31
0   0   220 170 165 11  148 0   0   52  0   233 0   241 131 83  173 196 0   0
204 0   0   0   0   0   0   0   92  225 0   0   0   141 159 182 0   0   0   143
141 178 217 74  0   174 243 164 200 98  138 122 67  44  34  96  0   0   68  118
133 227 39  0   0   118 234 247 38  0   0   0   0   0   0   0   243 247 108 153
54  185 145 0   0   9   102 9   57  0   159 210 128 152 171 4   0   0   118 139
225 161 52  17  0   0   115 129 0   0   170 0   0   0   0   83  45  0   204 91
212 57  167 39  174 0   0   0   0   89  178 0   197 0   0   219 0   0   0   0
173 113 78  184 115 48  107 253 0   0   53  216 0   0   109 245 0   102 42  26
251 187 218 234 139 140 84  101 0   0   64  102 0   0   0   0   106 111 237 26
164 142 31  222 63  218 252 0   0   228 151 76  169 0   95  153 168 195 157 127
141 157 99  86  156 0   0   109 0   227 97  54  0   0   144 11  237 169 67  53
171 211 226 0   0   156 208 207 0   0   0   0   0   249 56  229 194 48  216 197
29  200 99  0   188 160 178 199 145 244 0   0   162 163 254 201 0   120 239 5
51  134 175 0   193 216 79  49  89  86  180 0   0   0   0   0   35  37  42  2

在这个矩阵中,零 (0) 代表墙壁,正数代表颜色。如您所见,矩阵被墙(即零)分为区域和岛屿(对角线零也算作墙)。我需要一个程序来返回一个岛屿列表,包括该地区的所有数字。 (例如,一个列表包括第一个岛上的所有数字,然后是一个列表,包括第二个岛上的所有数字等等)我在下面写了一个程序(它不完整)但它达到了递归限制。

为了给出一些观点,我在这里尝试构建的是一个程序,可以平均每个岛屿的颜色。也就是说,我需要将某个岛上的每个数字转换为一个平均值,即该岛上所有数字的平均值,但我中途卡住了。我使用了递归算法,因为它对我来说最有意义。

def rec_appender(img,r,c,lst):
n_rows,n_cols=len(img),len(img[0])
if r<0 or c<0 or r>=n_rows or c>=n_cols: # check out actual borders
    return
if img[r][c] == 0:
    return
lst.append(img[r][c])
neigh_list=[[-1,0],[+1,0],[0,-1],[0,+1]]
for neigh in neigh_list:
    rec_appender(img,r+neigh[0],c+neigh[1],lst)


def averager(img):
lst = []
n_rows,n_cols=len(img),len(img[0])
for r in range(0,n_rows):
    for c in range(0,n_cols):
        if img[r][c] != 0: # is wall
            rec_appender(img,r,c,lst)

第二个函数检查矩阵中的所有点,如果它们不是墙,则参考第一个函数。

第一个函数将该点附加到列表中,然后检查它的邻居是否属于同一个岛,如果它们是岛的一部分,则将它们递归地添加到列表中。 (代码不完整,因为您可以看到岛屿不会分开,但我的问题是递归限制)

【问题讨论】:

  • 它有缩进?
  • 当你说平均时,你是在谈论颜色平均?我的意思是,一个岛屿的平均值是一种颜色?
  • 是的,一个岛屿只有一种颜色(即数字)。不同的颜色与不同的岛屿一样多(除非平均值巧合相等)
  • 然后解决方案将是每个岛屿的颜色列表(平均颜色),一个岛屿一个

标签: python recursion matrix graph-coloring


【解决方案1】:

好吧,这应该可行,在 dfs() 方法中,您对板上的每个单元格进行迭代,然后当您发现一个未访问过的单元格时,您可以使用方法 _dfs() 托盘访问整个岛,每次结束访问island 你将得到颜色的总和,然后除以_dfs()访问的单元格总数。我使用 DFS 算法的修改版本,你可以找到更多关于它的信息here。

def dfs(colors: list[list[int]]):

    mask=[ [False]*len(colors[0]) for _ in range(len(colors))]

    islands_average:list[float] = []

    for i in range(len(colors)):
        for j in range(len(colors[0])):
            if not mask[i][j] and colors[i][j]!=0 :
                sum_for_average = [0]
                total_colors=_dfs(i,j,colors, mask, sum_for_average)
                average = sum_for_average[0]/total_colors 
                islands_average.append(average)
                
    return islands_average 


def verify_pos(colors,x,y):
    return  x>=0 and x < len(colors) and
            y>=0 and y < len(colors[0]) 

def _dfs(x:int,y:int,colors, mask, island_average):
    
    mask[x][y] = True
    island_average[0] +=colors[x][y]
    total = 1

    for k in range(4):
        xx = x + helper_x[k]
        yy = y + helper_y[k]
        if verify_pos(colors,xx,yy) and colors[xx][yy]!=0 and not mask[xx][yy]:
            total+=_dfs(xx,yy,colors,mask,island_average)

    return total


编辑:我假设你有如何将颜色转换成矩阵,你可以按照下面的方式进行

def get_matrix(string:str):
    sol=[]
    for row in string.split("
"):
        sol.append([ int(c) for c in row.split(' ') if c!=''])
    return sol

EDIT2:算法的启动方法是dfs(colors),参数colors是颜色列表的列表,您可以使用方法get_matrix(string)从输入字符串格式中获取颜色。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    相关资源
    最近更新 更多