Common methods:
Idle workers "steals" work
Very invasive, difficult to scale above ~50 workers
Given a CSP P <$\mathcal{X},\mathcal{D},\mathcal{C}$>:
A decomposition is a process that produces a list of CSPs, called subproblems $s_1, s_2, ..., s_n$, such that
$$\bigcup_{i=1}^n s_i = P$$
xs <- list of variables
for(i <- 0 until xs.length) {
decomp <- generate(xs[0], ..., xs[i])
if(decomp.length >= n)
return decomp
}
return decomp
q <- new max-Priority Queue
q.add(cartProd(P), P)
while(q.size != n) {
sp <- q.poll()
for(c <- sp.children)
q.add(cartProd(c), c)
}
return content of q
OscaR is a Scala toolkit for solving Operations Research problems.
It includes tools to solve a great variety of problems:
Difficult to impossible.
OscaR-CP is a "low-level" solver, not a modelisation language!
Main motivation: simple serialization of models over the network.
$\rightarrow$ implementation on OscaR-CP
class SendMoreMoney extends ModelDeclaration {
val all = Array.fill(8)(IntVar(0, 9))
val Array(s, e, n, d, m, o, r, y) = all
//SEND, MORE and MONEY must no start with a 0
add(s > 0)
add(m > 0)
//All the variables must have a different value
add(AllDifferent(all))
//And we have the main constraint
add( s*1000 + e*100 + n*10 + d +
m*1000 + o*100 + r*10 + e ===
m*10000 + o*1000 + n*100 + e*10 + y)
}
object MySolver extends SolverApp[String] with MIPSolving {
override val modelDeclaration = new SendMoreMoney()
//Solution handler
onSolution { modelDeclaration.all.map(_.min).mkString(",") }
//Display first solution
println(solve().head)
}
$ java MySolver
9,5,6,7,1,0,8,2
object MySolver extends SolverApp[String] with MIPSolving
with SequentialCPSolving {
override val modelDeclaration = new SendMoreMoney()
//Solution handler
onSolution { modelDeclaration.all.map(_.min).mkString(",") }
//Add a CP search
setCPSearch(Branchings.binaryStatic(modelDeclaration.all))
//Display first solution
println(solve().head)
}
$ java MySolver mip
9,5,6,7,1,0,8,2
$ java MySolver cp
9,5,6,7,1,0,8,2
object MySolver extends SolverApp[String] with MIPSolving
with SequentialCPSolving
with ParallelCPSolving {
override val modelDeclaration = new SendMoreMoney()
val vars = modelDeclaration.all
//Add a CP search
setCPSearch(Branchings.binaryStatic(vars))
//Add an EPS decomposition
setCPDecompositionStrategy(new CartProdRefinement(vars, Branchings.binaryStatic(vars)))
//Solution handler
onSolution { vars.map(_.min).mkString(",") }
//Display first solution
println(solve().head)
}
$ java MySolver parallel-cp -n 8
# some solver output
9,5,6,7,1,0,8,2
References: see my master's thesis and the followup paper at CP2016
Computational resources have been provided by the Consortium des Équipements de Calcul Intensif (CÉCI), funded by the Fonds de la Recherche Scientifique de Belgique (F.R.S.-FNRS) under Grant No. 2.5020.11