Skip to content

Instantly share code, notes, and snippets.

@alexaandru
Last active August 29, 2015 14:00
Show Gist options
  • Save alexaandru/11027091 to your computer and use it in GitHub Desktop.
Save alexaandru/11027091 to your computer and use it in GitHub Desktop.
Visualization of "Vehicle Routing" problems & solutions
library(RColorBrewer)
# Return full path to problem data file.
dataFileFullPath <- function(fname) {
paste("data", fname, sep="/")
}
# Returns solution for a given problem.
computeSolutionFor <- function(fname) {
cacheFile <- paste("solutions", fname, sep="/")
if (file.exists(cacheFile)) {
sol <- system(paste('cat', cacheFile), intern=T)
} else {
# This is for the standard, python solver
#sol <- system(paste('python solver.py', dataFileFullPath(fname)), intern=T)
sol <- system(paste('python solver.py', dataFileFullPath(fname)), intern=T)
}
cost <- as.numeric(substr(sol[1], 1, nchar(sol[1])-1))
solutions <- sapply(sol[2:length(sol)], function(a) as.numeric(unlist(strsplit(a, " ")))+1)
list(cost=cost, solutions=solutions)
}
# Loads one data file and returns the list of cities.
loadDataFile <- function(fname) {
z <- read.table(dataFileFullPath(fname), header=FALSE, skip=1);
colnames(z) <- c("demand", "x", "y")
z
}
# Plots one instance of the problem, as defined in fname, including the solution.
plotInstance<- function(fname) {
cities <- loadDataFile(fname)
z <- computeSolutionFor(fname)
cost <- z$cost
plot(0, 0, type="b", xlim=c(min(cities$x), max(cities$x)), ylim=c(min(cities$y), max(cities$y)),
main=paste("Vehicle Routing", fname), xlab="x", ylab="y", cex.main=1.55)
colors <- colorRampPalette(brewer.pal(9, "Paired"))(length(z$solutions))
for (i in 1:length(z$solutions)) {
route <- unlist(z$solutions[i])
color <- colors[i]
tsp <- cities[route, c(2:3)]
tsp <- rbind(tsp, tsp[1,])
points(tsp, type="l", col=color)
points(tsp, cex=0.6, pch=16, col="black")
points(tsp[1,], cex=1.1, pch=19, col="red")
}
mtext(formatC(cost, format="d", big.mark=","), line=0.2, outer=F, col="#333333", cex=0.85)
}
# Plots multiple data instances (all found in _metadata by default).
# If only specific instances need to be plotted, then limit can be passed a vector
# of their IDs (e.g. c(1,3,5) would only plot problems #1, #3 and #5).
plotMulti <- function(limit=NULL, plotSol=T, fname = './_metadata') {
z <- read.table(fname, header=F, sep=' ', skip=3)
names <- lapply(as.character(z$V2), function (a) substr(a,8,nchar(a)-1))
if (!is.null(limit)) {
names <- names[limit]
}
if (length(names) > 1) {
par(mfrow=c(2,length(names)/2))
} else {
par(mfrow=c(1,1))
}
lapply(names, plotInstance)
}
#png(width=1600, height=900, res=96, antialias="subpixel", filename="out.png")
plotMulti() # pass a vector of problem #s to restrict plot to them alone, e.g. plotMulti(1:2)
#dev.off()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment