18×24二维数组中生成排除阻塞位置的随机坐标方案咨询
这个问题我之前做网格随机生成的时候踩过坑!当阻塞位置占比高到一定程度,那种“生成-检查-重试”的循环会不停撞墙,效率低到离谱。给你几个亲测好用的优化方案,按你的场景优先推荐:
方案1:预先生成可用位置池(最适合你的18×24小网格)
你的网格总共才432个位置,哪怕一半被阻塞,可用位置也才200多,完全可以提前把所有非阻塞位置一次性列出来,之后每次随机选就行——每次获取都是O(1)时间,零重试。
举个Python实现的例子:
import random # 假设你的阻塞位置列表是blocked_positions,比如[(3,5), (7,2), ...] # 先把阻塞位置转成集合,后续查找更快(这个优化不管用哪种方案都建议做) blocked_set = set(blocked_positions) # 预生成所有可用位置 available_positions = [] for x in range(18): for y in range(24): if (x, y) not in blocked_set: available_positions.append((x, y)) # 每次获取随机位置的函数 def get_random_free_pos(): return random.choice(available_positions)
如果阻塞位置是动态变化的(比如运行中会新增/解除阻塞),只要维护好available_positions列表就行——新增阻塞时移除对应位置,解除时加回去,比每次重新遍历网格高效多了。
方案2:优化版拒绝采样(适合超大网格,不想预存所有位置)
要是你的网格特别大(比如1000×1000),预存所有可用位置太占内存,可以用这种“计数定位”的方法:
- 先算出可用位置总数:
total_available = 18*24 - len(blocked_set) - 生成一个0到
total_available-1的随机数n,代表要找第n个可用位置 - 遍历网格,数到第n个非阻塞位置直接返回
代码示例:
import random blocked_set = set(blocked_positions) total_cells = 18 * 24 total_available = total_cells - len(blocked_set) def get_random_free_pos(): target_idx = random.randint(0, total_available - 1) current_count = 0 for x in range(18): for y in range(24): if (x, y) not in blocked_set: if current_count == target_idx: return (x, y) current_count += 1
这种方法最多遍历一次网格,不会像原始方法那样无限重试,效率稳定得多。
额外实用小技巧
- 一定要把阻塞位置存成集合:列表的
in操作是线性遍历,集合是哈希查找,速度差好几个数量级——哪怕你坚持用原始的重试方法,转成集合也能大幅提升效率。 - 如果阻塞位置有规律(比如某几行/列全堵),可以直接在生成坐标时跳过这些行/列:比如某3行全是阻塞,那生成x的时候直接从剩下的15行里选,再生成y,减少无效检查。
内容的提问来源于stack exchange,提问作者slin
相关产品推荐
相关产品推荐

