Algorithm 带条件的图遍历特定垂直
我有一个与下面类似的无向图,我需要实现一个图遍历算法。 示例:Algorithm 带条件的图遍历特定垂直,algorithm,graph,graph-traversal,Algorithm,Graph,Graph Traversal,我有一个与下面类似的无向图,我需要实现一个图遍历算法。 示例: 其思想是每个顶点都是一座城市,每个边缘都是一条道路。 边的权重表示穿过指定边所需的时间。 条件是: 每个边都在指定的时间窗口中打开以进行遍历:time Open1、time Open2、TimeClose1、time Close2-当前时间必须在这些时间间隔内才能遍历边。 只能访问某些顶点。每个顶点必须在指定的时间窗口中至少访问一次:time Open1、time Open2、TimeClose1、time Close2-当前时间
其思想是每个顶点都是一座城市,每个边缘都是一条道路。
边的权重表示穿过指定边所需的时间。
条件是:
必须访问的顶点及其时间窗口(不考虑带-1的值):
边在以下时间窗口中打开(不考虑带-1的值 (对价): 所以基本的想法是从顶点0开始,找到最短的路线来穿越 顶点1、4和5考虑到指定的时间
此外,如果您已经完成了0-1,但无法使用1-5,则可以执行0-1-0-1-5。
我现在正在使用的一个可能的解决方案是:
从0开始。在最短的时间内找到要标记的最近顶点(我使用 改进的Dijkstra算法)。这样做,直到我标记了所有需要的顶点
问题是我认为我没有找到所有的可能性,因为正如我所说的 你也可以像0-1-0-1-5组合那样四处移动,最终你可能会得到一条更短的路线 为了更清楚,我必须找到最短路径,以便从顶点0开始,以一个目标顶点结束,同时根据对边和目标顶点施加的条件访问所有其他目标顶点至少一次
例如:
一个可能的解决方案是0-4-3-5-1,总时间为60+50+60+50=220
从0开始,我也可以直接到5,但如条件中所述,以标记顶点5 我的累计时间必须在170到450之间。另外,如果我选择0-4,我不能使用edge 4-2,因为它在80打开,而我的累积时间是60。注:我可以使用0-4-3,因为4-3在60打开,而执行0-4需要的时间等于60 首先,我将使用最多20个顶点和 最多大约50个边 解决方案1:
0
1 4 5 0 2 5 0 2 3 0 1 3 我所做的是通过访问每个相邻顶点来遍历图形,构建类似于树的东西。我在以下情况下停止扩展分支:
1.我有太多的重复项,就像我有0 1 0 4 0 1 0-因此我停止,因为我有一组重复的0值,即4
2.我找到一条包含所有要标记顶点的道路
3.我发现一条路比另一条整条路要长
4.无法创建其他节点,因为边缘已关闭
解决方案2:
以@Boris Strandjev为例,但我有一些问题:
我必须在其间隔内访问节点1、4和5至少一次,允许但不标记间隔外的访问。对于一个顶点,我有{(
Step1:
{<0, 000>, 0} I can visit - {<1, 100>, 60} - chosen first lowest val
- {<4, 010>, 60}
- {<5, 000>, 60}
Step2:
{<1, 100>, 60} - {<0, 100>, 120}
- {<2, 100>, 110} - chosen
- {<5, 100>, 110}
Step3:
{<2, 100>, 110} - {<1, 100>, 160} - if I choose 1 again I will have a just go into a loop
- {<4, 110>, 170}
Step4:
{<4, 110>, 170} - {<0, 110>, 230}
- {<2, 110>, 230}
- {<3, 110>, 220} - chosen
Step5:
{<3, 110>, 220} - {<4, 110>, 270} - again possible loop
- {<5, 111>, 280}
Step6:
{<5, 111>, 280} - I stop Path: 0-1-2-4-3-5 cost 280
步骤1:
{,0}我可以访问-{,60}选择的第一个最低值
- {, 60}
- {, 60}
步骤2:
{, 60} - {, 120}
-{,110}-选择
- {, 110}
步骤3:
{,110}-{,160}-如果我再次选择1,我将有一个进入循环的循环
- {, 170}
步骤4:
{, 170} - {, 230}
- {, 230}
-{,220}-选择
步骤5:
{,220}-{,270}-同样可能的循环
- {, 280}
步骤6:
{,280}-I停止路径:0-1-2-4-3-5成本280
编辑:我最终使用了上述两种解决方案的组合。一切似乎都正常。我没有看到对图形中的顶点或边的数量有严格限制,因此如果我的解决方案不适用于您,请原谅。如果您需要任何改进,请给予更严格的限制 一种可能的解决方案是扩展节点的定义。不要只将城市视为图形中的节点,而是添加更多属性。保持边定义隐式,在运行时生成传出边,以便节省内存 现在请参见:
可以将节点定义为以下三项的组合: -节点所指的城市。 -访问时间 -已访问目标节点的位图(以便您可以判断是否已访问所有目标) 现在,边有点复杂-它们引导您从一个城市到另一个城市,但每个边也会更改相邻节点的时间。还可以在每个步骤中不断更新目标节点位图 下面是一个例子:
从
开始 如果你穿过边缘0-4,你会发现自己在节点
继续以这种方式在节点之间移动,使用Dejkstra算法,您将找到您的解决方案(当您扩展节点定义时,现在甚至会考虑环形)。只要您在位图中设置了所有位的节点中,您就找到了解决方案
在这种解决方案中使用的节点数量不太容易计算,但对于相对有限的节点数量和非常有限的目标城市数量,它应该可以工作(问题是生成的节点数量相对于
Edge To1 Tc1 To2 Tc2
0-1 0 770 -1 -1
0-4 0 210 230 770
0-5 0 260 -1 -1
1-2 0 160 230 770
1-5 40 770 -1 -1
2-4 80 500 -1 -1
3-4 60 770 -1 -1
3-5 0 770 -1 -1
Step1:
{<0, 000>, 0} I can visit - {<1, 100>, 60} - chosen first lowest val
- {<4, 010>, 60}
- {<5, 000>, 60}
Step2:
{<1, 100>, 60} - {<0, 100>, 120}
- {<2, 100>, 110} - chosen
- {<5, 100>, 110}
Step3:
{<2, 100>, 110} - {<1, 100>, 160} - if I choose 1 again I will have a just go into a loop
- {<4, 110>, 170}
Step4:
{<4, 110>, 170} - {<0, 110>, 230}
- {<2, 110>, 230}
- {<3, 110>, 220} - chosen
Step5:
{<3, 110>, 220} - {<4, 110>, 270} - again possible loop
- {<5, 111>, 280}
Step6:
{<5, 111>, 280} - I stop Path: 0-1-2-4-3-5 cost 280
Vertex To1 Tc1 To2 Tc2
1 0 40 80 120
2 40 80 -1 -1
3 0 400 -1 -1
4 30 80 120 190
Edge To1 Tc1 Weight
1-2 0 770 50
1-4 30 70 30
1-3 0 400 30
3-4 100 200 50
2-4 0 400 20