Huawei CodeCraft 2016 初赛解析

问题定义

给定一个带权重的有向图G=(V,E),V为顶点集,E为有向边集,每一条有向边均有一个权重。对于给定的顶点s、t,以及V的子集V’,寻找从s到t的不成环有向路径P,使得P经过V’中所有的顶点(对经过V’中节点的顺序不做要求)。

若不存在这样的有向路径P,则输出无解,程序运行时间越短,则视为结果越优;若存在这样的有向路径P,则输出所得到的路径,路径的权重越小,则视为结果越优,在输出路径权重一样的前提下,程序运行时间越短,则视为结果越优。

说明:
1)图中所有权重均为[1,20]内的整数;
2)任一有向边的起点不等于终点;
3)连接顶点A至顶点B的有向边可能超过一条,其权重可能一样,也可能不一样;
4)该有向图的顶点不会超过600个,每个顶点出度(以该点为起点的有向边的数量)不超过8;
5)V’中元素个数不超过50;
6)从s到t的不成环有向路径P是指,P为由一系列有向边组成的从s至t的有向连通路径,且不允许重复经过任一节点;
7)路径的权重是指所有组成该路径的所有有向边的权重之和。

输入与输出

输入文件格式

以两个.csv 文件(csv 是以逗号为分隔符的文本文件)给出输入数据,一个为图的数据(G),一个为需要计算的路径信息(s,t,V’)。文件每行以换行符(ASCII’\n’即0x0a)为结尾。

1)图的数据中,每一行包含如下的信息:
LinkID,SourceID,DestinationID,Cost
其中,LinkID 为该有向边的索引,SourceID 为该有向边的起始顶点的索引,DestinationID为该有向边的终止顶点的索引,Cost 为该有向边的权重。顶点与有向边的索引均从0 开始 编号(不一定连续,但用例保证索引不重复)。

2)路径信息中,只有一行如下数据:
SourceID,DestinationID,IncludingSet
其中,SourceID 为该路径的起点,DestinationID 为该路径的终点,IncludingSet 表示必须经过的顶点集合V’,其中不同的顶点索引之间用’|’分割。

输出文件格式

输出文件同样为一个.csv 文件。
1)如果该测试用例存在满足要求的有向路径P,则按P 经过的有向边顺序,依次输出有向边的索引,索引之间用’|’分割;
2)如果该测试用例不存在满足要求的有向路径P,则输出两个字符NA;
3)只允许输出最多一条有向路径。

求解算法

首先,这是一个NP-Hard问题。考虑问题的一种特殊情况,当寻路的必经节点为所有节点的时候,问题等价于求一个有向图的哈密尔顿回路。因此我们认为当节点规模足够大的时候,必须使用启发式算法才能在有效时间内求解。

我们尝试了多种启发式算法,寻路策略也探索了很多,其中的曲折等后续有时间了再补上。最后使用了模拟退火算法+蚁群算法求解,从竞赛的排名来看,这两种算法得到了非常好的效果。

这里是我们的算法实现。

0%