启发式算法 刘本圆 122260910059 本次程序作业的目的是找到Steiner Triple System (STS). 我们输入节点个数,程序需要找到一个由三元子集 合构成的集合,其中每两个节点组成的配对只能出现在一个唯一的三元子集合中。 方法介绍 由双计数方法可知STS(v)中三元子集合的个数为 子集合的数量,直到数量达到 个,因此我们可以使用爬山方法逐步增加符合条件的 时程序结束。伪代码如下: live_point = [] // 定义出现次数小于(v-1)/2的点为live point live_pair = [] // 定义还没有出现在现有block中的配对为live pair flag // 单位矩阵,记录相应节点对是否出现在集合中 block // 最终结果 while num_block < v*(v-1)/6: 更新live_point; 随机选择一个live point x; 更新live_pair,将尚未与x配对的点加入live_pair中; 随机在live_pair中选择两个尚未与x配对的点y, z; if {y,z}为live pair: 加入block; 更新flag; else: 将目前存在在block中的{u,y,z}替换为{x,y,z}; 更新flag; 输出结果 当输入的v不符合条件时,程序会给出提示 若输入的v符合条件,程序会返回STS(v)。以STS(7)为例: STS(9)的结果为: 此外,为了检验输出的STS是否符合条件,程序还会输出flag矩阵: 我们可以看到flag矩阵中各个节点对出现次数为1,说明返回的结果是STS。 当我们逐渐增大v时,时间开销并不会增长太多。例如当v=61时,耗时约为0.25s,可知爬山算法效率较 高,随机采样的情况下一般不会出现停滞在固定的block数量无法增加的情况。