问题:计算从A到Z之间的最优时效路径
为此做了一个示例数据,如下:
本帖隐藏的内容
netE.rar
(190 Bytes)
本附件包括:- netE.csv
- #读入数据
- edges <- read.csv("netE.csv", header=T,stringsAsFactors = FALSE)
- #不考虑时间约束的网络图
- net_g <- graph_from_data_frame(d = edges[,-3], directed = TRUE)
- l1 <- layout_on_grid(net_g)
- plot(net_g,
- vertex.size = 24,
- vertex.label.cex = 1.2,
- vertex.label.dist = 3,
- edge.color = "tomato",
- edge.arrow.size = 0.3,
- layout = l1
- )
不考虑时间约束的网络图
使问题复杂化的是,从一个节点到下一个节点的行程时间如果超过下一个节点的出发时间,需要等一天,也就是相应的形成时间增加24小时,导致上面这个网络里的每条边的耗时是不确定的。
思路是这样的,针对有向网络,如果A出发可以去n个节点,比如可以去B,也可以去C,则将A拆成n个,A1去节点B,A2去节点C;其他节点同样处理,比如B1可以去C,B2可以去D。节点拆分后,edge也增加了,比如A1-B1, A1-B2 。这样处理后,我们就可以根据约束条件计算每一条edge的耗时,或者是标准时间,或者是标准时间+24 。然后即可以用igraph生成网络,并计算节点之间的最短路径。
- #考虑时间约束
- edges <- edges %>% arrange(from,to)
- branches <- table(edges[,1])
- f<-levels(as.factor(edges[,1]))
- #调整from
- nf<-NULL
- for (i in 1:length(f)) {nf<-append(nf,paste(f[i],1:branches[f[i]],sep=""))}
- edges[,1]<-nf
- #调整to
- nedge<- data.frame()
- for (j in 1:dim(edges)[1]) {
- if (edges[j,2]!="E"){
- tmp<-NULL
- k=1
- repeat {
- tmp<-rbind(tmp,edges[j,])
- k=k+1
- if (k>branches[edges[j,2]]) break
- }
- tmp[,2]<-paste(edges[j,2],1:branches[edges[j,2]],sep="")
- nedge <- rbind(nedge,tmp)
- }
- else
- nedge <- rbind(nedge,edges[j,])
- }
- #调整weight
- nedge[,3]<-parse_date_time(nedge[,3],"%H:%M",exact = TRUE)
- for (i in 1:dim(nedge)[1]) {
- if (nedge[i, 2] != "E") {
- if (nedge[i, 3] + 3600 * nedge[i, 4] >= (nedge[which(nedge[, 1] == nedge[i, 2]), ])[1, 3])
- nedge[i, 4] <- nedge[i, 4] + 24
- }
- }
- #增加A
- nedge<-nedge[,-3]
- nedge<-rbind(nedge,data.frame(from=rep("A",branches["A"]),to=paste("A",1:branches["A"],sep=""),weight=rep(0,4)))
- #调整后的网络
- net_n <- graph_from_data_frame(d = nedge,directed = TRUE)
- l2 <- layout_on_grid(net_n)
- plot(net_n,
- vertex.size = 24,
- vertex.label.cex = 1.2,
- vertex.label.dist = 3,
- edge.color = "tomato",
- edge.arrow.size = 0.3,
- layout = l2
- )
调整后的网络图如下:
经过上述调整,我们可以计算最短路径
- shortest_paths(net_n,"A","E")[[1]]
- #最优路径的结果如下
- #[1] A A2 C1 D1 E
- #解读为ACDE是耗时最短的方案
- shortest.paths(net_n,"A","E") #计算该路径的最短耗时
- #3.5
- shortest.paths(net_n) #生成每个节点之间的最短耗时矩阵
提醒:
1、上述网络是有向的;
2、上述代码只计算了从A到E的路径,计算其他区间点,需要对代码略作调整;
3、这种方式的缺点是,如果节点太多,可能会极大地增加计算量。



雷达卡







京公网安备 11010802022788号







