You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成器转列表过大致IDE崩溃,如何限制四色解输出数量?

问题:限制四色定理着色方案生成器的输出数量

我用Python实现了基于四色定理的多边形着色功能,代码返回生成器对象。处理少量多边形时运行正常,但处理50个美国州的数据集时,生成的解数量过多,转换为列表会导致IDE崩溃。我希望限制生成的解数量到几千个,再从中筛选颜色分布最均匀的方案。

我尝试在生成器内添加计数器限制yield次数,但返回了空生成器,修改后的代码片段如下:

yield_counter = 0
for s in solve(X, Y, []):
    yield_counter +=1
    s = partial + [u for u in s if not isinstance(u, int)]
    s.sort()
    yield s
    if yield_counter == 100:
        break           

原生成器函数及调用代码:

def colour_map(nodes, edges, ncolours=4):
    colours = range(ncolours)
    # 每个节点关联的边
    node_edges = dict((n, set()) for n in nodes)
    for e in edges:
        n0, n1 = e
        node_edges[n0].add(e)
        node_edges[n1].add(e)

    for n in nodes:
        node_edges[n] = list(node_edges[n])
    # 构建覆盖集合
    coloured_edges = list(product(colours, edges))
    X = nodes + coloured_edges
    # 子集映射
    Y = dict()
    # 主行
    for n in nodes:
        ne = node_edges[n]
        for c in colours:
            Y[(n, c)] = [n] + [(c, e) for e in ne]
    # 虚拟行
    for i, ce in enumerate(coloured_edges):
        Y[i] = [ce]
    X = exact_cover(X, Y)
    # 固定前两个节点的颜色
    partial = [(nodes[0], 0), (nodes[1], 1)]
    for s in partial:
        select(X, Y, s)
    for s in solve(X, Y, []):
        s = partial + [u for u in s if not isinstance(u, int)]
        s.sort()
        yield s

# 调用生成器
all_solutions = colour_map(nodes, adjacent_polygons_graph, ncolours=3)
solution_list = list(all_solutions)

解决方案

方法1:修正生成器内部的计数器逻辑

你的计数器逻辑本身没有问题,大概率是solve(X,Y,[])处理大数据集时需要较长时间才能产出第一个解,导致你误以为返回空生成器。可以调整计数器逻辑,同时添加调试输出确认解的产出:

def colour_map(nodes, edges, ncolours=4, max_solutions=1000):
    colours = range(ncolours)
    # 原函数的其他代码保持不变...
    
    yield_counter = 0
    for s in solve(X, Y, []):
        # 调试用:打印当前生成的解序号
        # print(f"生成第{yield_counter+1}个解")
        s = partial + [u for u in s if not isinstance(u, int)]
        s.sort()
        yield s
        yield_counter += 1
        if yield_counter >= max_solutions:
            break

调用时指定最大解数量:

all_solutions = colour_map(nodes, adjacent_polygons_graph, ncolours=3, max_solutions=1000)
solution_list = list(all_solutions)

方法2:转换列表时用迭代器切片(无需修改原生成器)

使用itertools.islice直接截取生成器的前N个元素,无需修改原colour_map函数,灵活性更高:

import itertools

all_solutions = colour_map(nodes, adjacent_polygons_graph, ncolours=3)
# 只保留前1000个解
solution_list = list(itertools.islice(all_solutions, 1000))

额外优化建议

  • 如果目标是筛选颜色分布最均匀的方案,无需生成大量解后再筛选:可以在生成每个解时,直接计算颜色分布的均匀度(比如统计各颜色使用次数的方差,方差越小越均匀),只保留当前最优的N个解,大幅减少内存占用。
  • 检查partial = [(nodes[0], 0), (nodes[1], 1)]的硬编码是否必要:固定前两个节点的颜色会减少解的数量,若不需要限制初始节点颜色,可删除这部分逻辑,增加解的多样性。

内容的提问来源于stack exchange,提问作者GBG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:44:50