Michael Powell skrev den 2014-11-20 01:11:
> For example, I am not entirely sure what to do with the callbacks.
>
> They aren't 'callbacks' in the sense that they are function pointers,
> true .NET delegates, can be satisfied with lambdas, although that would
> be great.
I noticed from the previous thread something which Sylvain Ducomman wrote:
"Finally, for use the IndexEvaluator2 callback, you don’t need really
implement this. You just create a function with the parameters accepted
by callback, and call the function "NewPermanentCallback(yourFunction)"
I haven't tried this, but perhaps the yourFunction argument can be a lambda?
> In fact they seem more like Listener patterns, or functors in C/C++
> vocabulary, in the sense that you derive classes and implement methods
> on your own.
>
> private class TestCallback1 : LongResultCallback1
> {
> public override long Run(long arg0)
> {
> return base.Run(arg0);
> }
> }
>
> private class TestCallback2 : LongResultCallback2
> {
> public override long Run(long arg0, long arg1)
> {
> return base.Run(arg0, arg1);
> }
> }
>
> Which is fine, but along which lines, would be helpful to know what arg0
> and arg1 are, what the purpose(s) of Run are. In fact more aptly named
> arguments would be better, if possible.
I am not entirely sure if you are only arguing for better documentation
here or if you really need instructions? If the latter, here are my
thoughts:
In Testcallback2.Run(), arg0 is the index of a decision variable and
arg1 is a value to evaluate.
If you have told MakePhase to use (an instance of) TestCallback2 as the
IntValueStrategy, this is what will happen:
a) The IntVarStategy decides to branch on a variable at indexIV.
b) The solver (not sure if this is technically correct, it may be some
other component responsible) then looks up what values are still valid
in the domain if the decision variable.
c) For each of the valid values, the solver will call
myTestCallback2.Run(), passing in the arguments arg0 = indexIV, arg1 =
[the value to evaluate].
d) For each call in c, the Run() function returns a (arbitrary) value. A
low return value means: try this first. If two domain values are scored
the same and there is no tie-breaking function defined, then the solver
will select the lower domain value.
e) After all calls in [c] have been made, the solver tries to apply the
domain value with the lowest score to the decision variable, which will
trigger a bunch of propagations. If any constraint is then broken, the
decision is refuted and the solver backtracks in the decision tree.
Otherwise it is committed and the solver gets the next IntVar to branch
on from the IntVarStrategy (go back to a)
So, in essence, TestCallback2.Run() is a sorting function.
Since TestCallback2 is a class, it may contain fields to remember
previous decisions and make smarter choices.
In the implementation I have made for creating sports match schedules, I
pass a reference to the array of decision variables to the constructor
of the class, which means that I can inspect all variables to see if
they are bound (and to which values) and adjust my evaluation accordingly.
Regards.
/ Otto D