1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#######################################################################
# 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)
}
|