R/write_TSPLIB.R

Defines functions write_TSPLIB.ETSP write_TSPLIB.ATSP write_TSPLIB.TSP write_TSPLIB

Documented in write_TSPLIB write_TSPLIB.ATSP write_TSPLIB.ETSP write_TSPLIB.TSP

#######################################################################
# TSP - Traveling Salesperson Problem 
# Copyrigth (C) 2011 Michael Hahsler and Kurt Hornik
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


## generic
write_TSPLIB <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) 
  UseMethod("write_TSPLIB")


## write a simple TSPLIB format file from an object of class TSP
## (contains a dist object or a symmetric matrix) 

## TSP has data as integer
write_TSPLIB.TSP <- function(x, file, precision = 6, 
  inf = NULL, neg_inf = NULL) {

  ## prepare data (NA, Inf)
  if(any(is.na(x))) stop("NAs not allowed!")
  x <- .replaceInf(x, inf, neg_inf)
  
  ## Concorde can handle UPPER_ROW and dist (lower triangle matrix) 
  ## is symmetric.
  format <- "EDGE_WEIGHT_FORMAT: UPPER_ROW"
  
  zz <- file(file, "w")
  
  cat("NAME: TSP",
    "COMMENT: Generated by write_TSPLIB (R-package TSP)",
    "TYPE: TSP",
    paste("DIMENSION:", n_of_cities(x)),
    "EDGE_WEIGHT_TYPE: EXPLICIT",
    format, 
    file = zz, sep = "\n")
  
  ## only integers can be used as weights
  if(storage.mode(x) != "integer") x <- x * 10^precision
  
  x <- suppressWarnings(as.integer(x))
  if(any(is.na(x))) stop("Integer overflow, please reduce precision.")
  
  cat("EDGE_WEIGHT_SECTION", x, file = zz, sep = "\n")
  cat("EOF", file = zz, sep = "\n")
  
  close(zz)
}


write_TSPLIB.ATSP <- function(x, file, precision = 6, inf = NULL, neg_inf = NULL) {
  
  ## prepare data (NA, Inf)
  if(any(is.na(x))) stop("NAs not allowed!")
  x <- .replaceInf(x, inf, neg_inf)
  
  format <- "EDGE_WEIGHT_FORMAT: FULL_MATRIX"
  
  zz <- file(file, "w")
  
  cat("NAME: ATSP",
    "COMMENT: Generated by write_TSPLIB (R package TSP)",
    "TYPE: ATSP",
    paste("DIMENSION:", n_of_cities(x)),
    "EDGE_WEIGHT_TYPE: EXPLICIT",
    format, 
    file = zz, sep = "\n")
  
  
  ## only integers can be used as weights
  if(storage.mode(x) != "integer") x <- x * 10^precision
    
  x <- suppressWarnings(as.integer(x))
  if(any(is.na(x))) stop("integer overflow, please reduce precision.")
  
  cat("EDGE_WEIGHT_SECTION", x, file = zz, sep = "\n")
  cat("EOF", file = zz, sep = "\n")
  
  close(zz)
}


## ETSP use data as real
write_TSPLIB.ETSP <- function(x, file, precision = 6, 
  inf = NULL, neg_inf = NULL) {

  if(any(is.na(x))) stop("NAs are not allowed!")
  if(any(!is.finite(x))) stop("Only finite values allowed!")
    
  if(ncol(x) == 2) type <- "EUC_2D"
  else if(ncol(x) == 3) type <- "EUC_3D"
  else stop("Only EUC_2D and EUC_3D supported.")
  
  zz <- file(file, "w")
  
  cat("NAME: ETSP",
    "COMMENT: Generated by write_TSPLIB (R package TSP)",
    "TYPE: TSP",
    paste("DIMENSION:", n_of_cities(x)),
    paste("EDGE_WEIGHT_TYPE:", type),
    file = zz, sep = "\n")
  
  ## fix row names
  rownames(x) <- NULL
  x <- do.call(data.frame, lapply(1:ncol(x), FUN = 
      function(i) sprintf(paste("%0.", precision, "e", sep=""), x[,i])))
  
  cat("NODE_COORD_SECTION", file = zz, sep = "\n")
  write.table(x, quote=FALSE, col.names = FALSE, file = zz) 
  cat("EOF", file = zz, sep = "\n")
  
  close(zz)
}

Try the TSP package in your browser

Any scripts or data that you put into this service are public.

TSP documentation built on April 30, 2018, 5:03 p.m.