context("MCFSolutions & co: S4 classes to encode min-cost-flow solutions")
test_that("Instantiation & validity", {
expect_true(validObject(new("SubProbInfo"))) # test the prototype
expect_silent(spi1 <- new("SubProbInfo", data.frame(groups=c('a','b'), flipped=logical(2), hashed_dist=c('a','b'),
resolution=c(1,10), lagrangian_value=c(.5, 2), dual_value=c(0,1),
feasible=c(TRUE, FALSE), exceedance=1, stringsAsFactors=F)
)
)
expect_true(validObject(spi1))
spi2 <- spi1
colnames(spi2)[1] <- "Subprob"
expect_error(validObject(spi2), "Cols 1-8 should be")
expect_true(validObject(new("NodeInfo"))) # test the prototype
expect_silent(ni1 <- new("NodeInfo",
data.frame(name='a', price=0.5, upstream_not_down=TRUE,
supply=1L, groups = as.factor('b'),
stringsAsFactors=F)
)
)
expect_silent(ni1f <- new("NodeInfo",
data.frame(name=c('b', 'c', 'd',
'(_Sink_)', '(_End_)'),
price=0.5,
upstream_not_down=c(TRUE, FALSE,
FALSE, NA, NA),
supply=c(1L,0L,0L,-1L,-2L), groups = as.factor('b'),
stringsAsFactors=F)
)
)
expect_equivalent(node.labels(ni1f), as.character(1:5))
expect_named(node.labels(ni1f),
c('b', 'c', 'd', '(_Sink_)', '(_End_)')
)
expect_silent(node.labels(ni1f) <- ni1f[['name']])
expect_equivalent(node.labels(ni1f), ni1f[['name']])
expect_error(new("NodeInfo",
data.frame(name='a', price='foo', upstream_not_down=FALSE,
supply=1L, groups = as.factor('b'),
stringsAsFactors=F)
),
"should be a numeric" # Not sure it's necessary, but insisting
) # that 'price' be double not integer
expect_error(new("NodeInfo",
data.frame(name=rep('a', 2), price=0, upstream_not_down=FALSE,
supply=1L, groups = as.factor('b'),
stringsAsFactors=F)
),
"unique"
)
expect_true(validObject(new("ArcInfo"))) # test the prototype
expect_silent(ai <- new("ArcInfo",
matches=data.frame(groups = as.factor('a'), upstream = factor('b', levels=node.labels(ni1f)),
downstream = factor(c('c','d'), levels=node.labels(ni1f)),
stringsAsFactors=F),
bookkeeping=data.frame(groups = as.factor('a'),
start = factor(c('c','d'),
levels=node.labels(ni1f)
),
end = factor('(_Sink_)',
levels=node.labels(ni1f)
),
flow=1L, capacity=1L,
stringsAsFactors=F)
)
)
expect_error(new("ArcInfo",
matches=data.frame(groups = as.factor('a'), upstream = as.factor('b'),
downstream = as.factor(c('c','d')),stringsAsFactors=F),
bookkeeping=data.frame(groups = as.factor('a'), start = as.factor(c('c','d')),
end = as.factor('(_Sink_)'), flow=1.5,
capacity=1L, stringsAsFactors=F)
), "should have type integer" # Not sure it's necessary, but insisting
) # that 'flow' be integer not double
expect_error(new("ArcInfo",
matches=data.frame(groups = as.factor('a'), upstream = as.factor('b'),
downstream = as.factor(c('c','d')),stringsAsFactors=F),
bookkeeping=data.frame(groups = as.factor('a'), start = as.factor(c('c','d')),
end = as.factor('(_Sink_)'), flow=-1L,
capacity=1L, stringsAsFactors=F)
), "should be nonnegative"
)
expect_error(new("ArcInfo",
matches=data.frame(groups = as.factor('a'),
upstream = as.factor('b'),
downstream=as.factor(c('c','d')),
stringsAsFactors=F),
bookkeeping=data.frame(groups=as.factor('a'),
start=as.factor(c('c','d')),
end=as.factor('(_Sink_)'), flow=2L,
capacity=1L, stringsAsFactors=F)
), "flow can be no greater than capacity"
)
expect_silent(mcf1f <- new("MCFSolutions", subproblems=spi1,nodes=ni1f,arcs=ai))
expect_silent(as(mcf1f, "FullmatchMCFSolutions"))
expect_equal(node.labels(mcf1f), node.labels(ni1f))
expect_silent(node.labels(mcf1f) <- paste0(node.labels(ni1f),"_") )
expect_equivalent(node.labels(mcf1f), paste0(node.labels(ni1f), "_") )
expect_equivalent(node.labels(mcf1f@nodes), paste0(node.labels(ni1f), "_") )
})
expect_setequal(names(getSlots("MCFSolutions")),
c("subproblems", "nodes", "arcs")
)# premise of c() method for MCFSolutions
test_that("c() methods", {
spi1 <- new("SubProbInfo",
data.frame(groups=c('a','b'), flipped=logical(2), hashed_dist=c('a','b'),
resolution=c(1,10), lagrangian_value=c(.5, 2), dual_value=c(0,1),
feasible=c(TRUE, FALSE), exceedance=1, stringsAsFactors=F)
)
spi2 <- new("SubProbInfo",
data.frame(groups=c('c'), flipped=logical(1), hashed_dist=c('a'),
resolution=c(1), lagrangian_value=c(.5), dual_value=c(0),
feasible=c(TRUE), exceedance=1, stringsAsFactors=F)
)
spi3 <- new("SubProbInfo",
data.frame(groups=c('d'), flipped=logical(1), hashed_dist=c('a'),
resolution=c(1), lagrangian_value=c(.5), dual_value=c(0),
feasible=c(TRUE), exceedance=1, stringsAsFactors=F)
)
expect_true(validObject(c(spi1, spi2)))
expect_true(validObject(c(spi1, spi2, spi3)))
expect_true(validObject(c(a=spi1, b=spi2))) # no confusion just b/c no `x=` arg!
ni1f <- new("NodeInfo",
data.frame(name=c('b', 'c', 'd',
'(_Sink_)', '(_End_)'),
price=c(0.5, 0.5,
NA_real_, # permissible for downstream nodes
0.5, 0.5),
upstream_not_down=c(TRUE, FALSE,
FALSE, NA, NA),
supply=c(1L,0L,0L,-1L,-2L), groups = as.factor('b'),
stringsAsFactors=F)
)
node.labels(ni1f) <- ni1f[['name']]
ni1f.a <- ni1f.b <- ni1f.c <- ni1f
ni1f.a[,'groups'] <- factor(rep('a', nrow(ni1f)))
ni1f.c[,'groups'] <- factor(rep('c', nrow(ni1f)))
expect_true(validObject(c(ni1f.a, ni1f.b)))
expect_true(validObject(c(ni1f.a, ni1f.b, ni1f.c)))
ni2 <- new("NodeInfo",
data.frame(name=c(letters[2:5], '(_Sink_)', '(_End_)'), price=0.5,
upstream_not_down=c(TRUE, rep(FALSE,3), NA, NA),
supply=c(1L, rep(0L,3),-1L,-2L), groups=as.factor('c'),
stringsAsFactors=F)
)
node.labels(ni2) <- ni2[['name']]
ni1ni2 <- c(ni1f, ni2)
expect_equal(ni1ni2$name, c("b", "c", "d", "(_Sink_)", "(_End_)", letters[2:5], "(_Sink_)", "(_End_)"))
expect_equal(levels(ni1ni2$groups), c("b", "c"))
expect_named(node.labels(ni1ni2), c("b", "c", "d", "(_Sink_)", "(_End_)", letters[2:5], "(_Sink_)", "(_End_)") )
expect_false( any(duplicated(node.labels(ni1ni2))) )
some_levs <- c(letters[2:4], '(_Sink_)', "(_End_)")
ai1 <- new("ArcInfo",
matches=data.frame(groups = factor('a'),
upstream = factor('b', levels=some_levs),
downstream = factor(c('c','d'), levels=some_levs),
stringsAsFactors=F),
bookkeeping=data.frame(groups = factor('a'),
start = factor(c('c','d'), levels=some_levs),
end = factor('(_Sink_)', levels=some_levs),
flow=1L, capacity=1L,
stringsAsFactors=F)
)
expect_true(validObject(ai1))
expect_true(validObject(c(ai1, ai1)))
expect_true(validObject(c(x=ai1, y=ai1, z=ai1)))
some_levs <- c(letters[2:5], '(_Sink_)', '(_End_)')
ai2 <- new("ArcInfo",
matches=data.frame(groups = factor('c'),
upstream = factor('b', levels=some_levs),
downstream = factor(c('c','d', 'e'), levels=some_levs),
stringsAsFactors = F),
bookkeeping=data.frame(groups = factor('c'),
start = factor(c('c','d'), levels=some_levs),
end = factor('(_Sink_)', levels=some_levs),
flow=1L, capacity=1L,
stringsAsFactors=F)
)
expect_true(validObject(ai2))
ai1ai2 <- c(ai1, ai2)
expect_equal(levels(ai1ai2@matches$groups), c("a", "c"))
expect_setequal(unique(as.character(ai1ai2@matches$upstream)), "b")
expect_setequal(unique(as.character(ai1ai2@matches$downstream)),
c("c", "d", "e")
)
expect_setequal(unique(as.character(ai1ai2@bookkeeping$end)), "(_Sink_)")
mcf1 <- new("MCFSolutions", subproblems=spi1, nodes=ni1f, arcs=ai1)
mcf2 <- new("MCFSolutions", subproblems=spi2,nodes=ni2,arcs=ai2)
expect_true(validObject(mcf1))
expect_true(validObject(mcf2))
expect_error(c(mcf1, mcf1), "uplicates")
expect_true(validObject(c(mcf1, mcf2)))
expect_true(validObject(c(y=mcf1, z=mcf2)))
mcf2f <- as(mcf2, "FullmatchMCFSolutions")
expect_is(c(mcf2f, mcf1), "FullmatchMCFSolutions")
expect_is(c(mcf1, mcf2f), "MCFSolutions")
})
test_that("nodeinfo getter",{
expect_silent(mcf <- new("MCFSolutions")) #prelim-
expect_true(validObject(mcf, complete=TRUE))#inaries
expect_is(nodeinfo(mcf@nodes), "NodeInfo")
expect_is(nodeinfo(mcf), "NodeInfo")
data <- data.frame(z = c(rep(0,10), rep(1,5)),
x = rnorm(15), fac=rep(c(rep("a",2), rep("b",3)),3))
f1 <- fullmatch(z~x, min.c=1, max.c=1, omit.fraction=.5, data = data)
expect_is(f1, "optmatch")
expect_false(is.null(attr(f1, "MCFSolutions")))
expect_is(nodeinfo(f1), "NodeInfo")
expect_null(nodeinfo(10))
})
test_that("NodeInfo to tibble converter", {
ni1f <- new("NodeInfo",
data.frame(name=c('b', 'c', 'd',
'(_Sink_)', '(_End_)'),
price=0.5,
upstream_not_down=c(TRUE, FALSE,
FALSE, NA, NA),
supply=c(1L,0L,0L,-1L,-2L), groups = as.factor('b'),
stringsAsFactors=F)
)
expect_silent(ni_tbl <- as(ni1f, "tbl_df"))
expect_is(ni_tbl$nodelabels, "factor")
expect_equivalent(as.character(ni_tbl$nodelabels),
as.character(1:5))
expect_null(names(ni_tbl$nodelabels))
node.labels(ni1f) <- ni1f[['name']]
expect_silent(ni_tbl <- as(ni1f, "tbl_df"))
expect_is(ni_tbl$nodelabels, "factor")
expect_equivalent(as.character(ni_tbl$nodelabels),
c('b', 'c', 'd', '(_Sink_)', '(_End_)')
)
expect_equivalent(levels(ni_tbl$nodelabels),
c('b', 'c', 'd', '(_Sink_)', '(_End_)')
) # default encoding would start w/ "(_End_)", "(_Sink_)"
})
test_that("Preserve levels when filtering a node info tibble",{
ni1f <- new("NodeInfo",
data.frame(name=c('b', 'c', 'd',
'(_Sink_)', '(_End_)'),
price=0.5,
upstream_not_down=c(TRUE, FALSE,
FALSE, NA, NA),
supply=c(1L,0L,0L,-1L,-2L), groups = as.factor('b'),
stringsAsFactors=F)
)
node.labels(ni1f) <- ni1f[['name']]
ni_tbl <- as(ni1f, "tbl_df")
expect_silent(ni_tbl_s <- dplyr::filter(ni_tbl, name %in% letters))
expect_is(ni_tbl_s$nodelabels, "factor")
expect_equivalent(levels(ni_tbl_s$nodelabels),
c('b', 'c', 'd', '(_Sink_)', '(_End_)')
)
})
test_that("Node labels getter",{
expect_silent(mcf <- new("MCFSolutions")) #prelim-
expect_true(validObject(mcf, complete=TRUE))#inaries
expect_is(node.labels(mcf@nodes), "character")
expect_is(node.labels(mcf), "character")
data <- data.frame(z = c(rep(0,10), rep(1,5)),
x = rnorm(15), fac=rep(c(rep("a",2), rep("b",3)),3))
f1 <- fullmatch(z~x, min.c=1, max.c=1, omit.fraction=.5, data = data)
expect_is(f1, "optmatch")
expect_false(is.null(attr(f1, "MCFSolutions")))
expect_is(node.labels(f1), "character")
expect_false(is.null(names(node.labels(f1))))
expect_null(nodeinfo(10))
})
test_that("filtering on groups/subproblem field", {
spi1 <- new("SubProbInfo",
data.frame(groups=c('a','b'), flipped=logical(2), hashed_dist=c('a','b'),
resolution=c(1,10), lagrangian_value=c(.5, 2), dual_value=c(0,1),
feasible=c(TRUE, FALSE), exceedance=1, stringsAsFactors=F)
)
expect_error(filter_by_subproblem(spi1, groups="a"), "implemented")
ni1f <- new("NodeInfo",
data.frame(name=c('b', 'c', 'd',
'(_Sink_)', '(_End_)'),
price=0.5,
upstream_not_down=c(TRUE, FALSE,
FALSE, NA, NA),
supply=c(1L,0L,0L,-1L,-2L), groups = as.factor('b'),
stringsAsFactors=F
)
)
node.labels(ni1f) <- ni1f[['name']]
expect_silent(ni1a <- filter_by_subproblem(ni1f, groups="b"))
expect_identical(ni1f, ni1a)
expect_silent(ni10 <- filter_by_subproblem(ni1f, groups="a"))
expect_is(ni10, "NodeInfo")
expect_equal(nrow(ni10), 0L)
ni2 <- new("NodeInfo",
data.frame(name=c('a', '(_Sink_)', '(_End_)'), price=0.5,
upstream_not_down=c(FALSE, NA, NA),
supply=c(0L,-1L,-2L), groups=as.factor('c'),
stringsAsFactors=F)
)
ni12 <- c(ni1f, ni2)
expect_silent(ni1b <- filter_by_subproblem(ni12, groups="b"))
expect_is(ni1b, "NodeInfo")
expect_equal(nrow(ni1b), 5L)
expect_silent(ni12a <- filter_by_subproblem(ni12, groups=c("b","c")))
expect_is(ni12a, "NodeInfo")
expect_equal(nrow(ni12a), 8L)
some_levs <- c(letters[2:4], '(_Sink_)', '(_End_)')
ai1 <- new("ArcInfo",
matches=data.frame(groups = factor('a'),
upstream = factor('b', levels=some_levs),
downstream = factor(c('c','d'), levels=some_levs),
stringsAsFactors=F),
bookkeeping=data.frame(groups = factor('a'),
start = factor(c('c','d'), levels=some_levs),
end = factor('(_Sink_)', levels=some_levs),
flow=1L, capacity=1L,
stringsAsFactors=F)
)
expect_error(filter_by_subproblem(ai1, groups="a"), "implemented")
mcf1 <- new("MCFSolutions", subproblems=spi1, nodes=ni1f, arcs=ai1)
expect_error(filter_by_subproblem(mcf1, groups="a"), "implemented")
})
test_that("Potentially unusual requirements of base functions",{
## de-duplication of row names when stacking data.frame-s
expect_true(formals(base::rbind.data.frame)[['make.row.names']])
df1 <- data.frame(x=1:2, y=3:4, row.names=c('a','b'))
df2 <- data.frame(x=3:4, y=3:4, row.names=c('a','B'))
df3 <- data.frame(x=5:6, y=3:4, row.names=c('b','a'))
expect_equal(row.names(rbind(df1, df2)), c("a", "b", "a1", "B"))
expect_equal(row.names(rbind(df1, df3)), c("a", "b", "b1", "a1"))
## char vecs can have repeats in row names
cvec <- letters
names(cvec) <- LETTERS
names(cvec)[1] <- "B"
expect_is(cvec, "character")
expect_named(cvec, c("B", LETTERS[-1L]))
expect_true(any(duplicated(names(cvec))))
})
test_that("NodeInfo subsetting", {
expect_silent(ni0_o <- nodes_shell_fmatch(c(1,2), c(3,4)))
expect_is(ni0_o, "NodeInfo")
expect_equal(nrow(ni0_o), 6)
expect_silent(ni0_n <- filter(ni0_o, name!=2 & name!=4))
expect_is(ni0_n, "NodeInfo")
expect_equal(nrow(ni0_n), 4)
})
test_that("Pull updated prices & supplies into a NodeInfo",{
expect_silent(ni0_o <- nodes_shell_fmatch(c(1,2), c(3,4)))
expect_true(all(ni0_o[['price']]==0))
ni0_n <- filter(ni0_o, name!=2 & name!=4)
expect_equal(nrow(ni0_n), 4) # unimportant in itself but presumed by next few lines
ni0_n@.Data[[which(ni0_n@names=="price")]] <- rep(1, 4)
ni0_n@.Data[[which(ni0_n@names=="supply")]] <- c(2, 0, -1, -1)
## (Now ni0_n has the form of an actual price/supply combo)
expect_silent(ni0 <- update.NodeInfo(ni0_o, ni0_n))
expect_equal(ni0[['price']], c(1, 0, 1, 0, 1, 1))
expect_equal(ni0[['supply']], c(2, 0, 0, 0, -1, -1))
expect_equal(update(ni0_o, ni0_n), ni0) # confirm `update()` dispatch
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.