[Scip] Problems with SCIPcopy() and SCIPcopyProb()

Daniel Karch karch at math.tu-berlin.de
Thu Dec 22 12:59:15 MET 2011


Hello Stefan,

thank you for your detailed answer. I have since reworked the code so that
the issue does not
arise anymore. Therefore I cannot see if your proposed fix would have
solved it, I am sorry.
But I have incorporated into my code.

However, I keep running into problems, mostly triggered by the RENS
heuristic.
I suppose that there are some issues in my code that surface now that the
heuristic creates a
copy of the SCIP instance.

The problem I have now is the following. I get the error

src/scip/var.c:8075: SCIPvarResetBounds: Assertion `SCIPvarGetTransVar(var)
== ((void *)0)' failed.

and the stack trace is

#0  0x00002aaaabf9e9d5 in raise () from /lib64/libc.so.6
#1  0x00002aaaabf9fed6 in abort () from /lib64/libc.so.6
#2  0x00002aaaabf97235 in __assert_fail () from /lib64/libc.so.6
#3  0x00000000006944fe in SCIPvarResetBounds (var=0x29078d0,
blkmem=0x2352540, set=0x2170ea0, stat=0x26fe6f0) at src/scip/var.c:8075
#4  0x00000000005cbe9a in SCIPprobResetBounds (prob=0x26fefd0,
blkmem=0x2352540, set=0x2170ea0, stat=0x26fe6f0) at src/scip/prob.c:514
#5  0x00000000005ed76b in freeTransform (scip=0x197c980) at
src/scip/scip.c:7302
#6  0x00000000005eee57 in SCIPfreeTransform (scip=0x197c980) at
src/scip/scip.c:7744
#7  0x00000000005e1fb8 in SCIPfreeProb (scip=0x197c980) at
src/scip/scip.c:4357
#8  0x00000000005d4513 in SCIPfree (scip=0x7fffffffd038) at
src/scip/scip.c:586
#9  0x0000000000812477 in SCIPapplyRens (scip=0x146d010, heur=0x1533ee0,
result=0x7fffffffd280, minfixingrate=0.5, minimprove=0.01, maxnodes=5000,
nstallnodes=500, startsol=108 'l', binarybounds=1, uselprows=0) at
src/scip/heur_rens.c:567
#10 0x0000000000812991 in heurExecRens (scip=0x146d010, heur=0x1533ee0,
heurtiming=44, result=0x7fffffffd280) at src/scip/heur_rens.c:695
#11 0x0000000000513201 in SCIPheurExec (heur=0x1533ee0, set=0x14711d0,
primal=0x1659be0, depth=0, lpstateforkdepth=-1, heurtiming=44,
ndelayedheurs=0x7fffffffd27c, result=0x7fffffffd280) at src/scip/heur.c:398
#12 0x000000000064f5bd in SCIPprimalHeuristics (set=0x14711d0,
stat=0x156b790, primal=0x1659be0, tree=0x17df730, lp=0x17d8830,
nextnode=0x0, heurtiming=44, foundsol=0x7fffffffd438) at
src/scip/solve.c:241
#13 0x000000000065accb in solveNode (blkmem=0x146f1b0, set=0x14711d0,
stat=0x156b790, origprob=0x1570bc0, transprob=0x17b6f00, primal=0x1659be0,
tree=0x17df730, lp=0x17d8830, relaxation=0x1659b70, pricestore=0x1887540,
sepastore=0x17a5650, branchcand=0x17d87a0, cutpool=0x17a56d0,
conflict=0x161f7e0, eventfilter=0x169e650, eventqueue=0x163dc40,
cutoff=0x7fffffffd5dc, unbounded=0x7fffffffd5d8, infeasible=0x7fffffffd5d4,
restart=0x7fffffffd768, afternodeheur=0x7fffffffd5cc) at
src/scip/solve.c:3327
#14 0x000000000065d4b7 in SCIPsolveCIP (blkmem=0x146f1b0, set=0x14711d0,
stat=0x156b790, mem=0x146d120, origprob=0x1570bc0, transprob=0x17b6f00,
primal=0x1659be0, tree=0x17df730, lp=0x17d8830, relaxation=0x1659b70,
pricestore=0x1887540, sepastore=0x17a5650, cutpool=0x17a56d0,
branchcand=0x17d87a0, conflict=0x161f7e0, eventfilter=0x169e650,
eventqueue=0x163dc40, restart=0x7fffffffd768) at src/scip/solve.c:3878
#15 0x00000000005ee4bc in SCIPsolve (scip=0x146d010) at src/scip/scip.c:7541
#16 0x0000000000633c2f in fromCommandLine (scip=0x146d010,
filename=0x7fffffffe29d "../fsg/polska.fsg") at src/scip/scipshell.c:135
#17 0x0000000000634461 in SCIPprocessShellArguments (scip=0x146d010,
argc=3, argv=0x7fffffffde38, defaultsetname=0xfdd27f "scipmincon.set") at
src/scip/scipshell.c:341
#18 0x0000000000408568 in runSCIP (argc=3, argv=0x7fffffffde38) at
src/cppmain.cpp:85
#19 0x00000000004086ad in main (argc=3, argv=0x7fffffffde38) at
src/cppmain.cpp:123

In my ProbData class I have implemented the scip_copy callback where I now
get the variable copies like this:

SCIP_VAR * y_uv_s = NULL;
sourcevar = this->y_vars(uv,s);
if( SCIPvarGetStatus(sourcevar) == SCIP_VARSTATUS_ORIGINAL &&
SCIPisTransformed(sourcescip)
) {
  sourcevar = SCIPvarGetTransVar(sourcevar);
}
SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevar, &y_uv_s, varmap,
consmap, global, &success) );
// Store y_uv_s somewhere.
...
SCIP_CALL( SCIPcaptureVar(scip, y_uv_s) );

and the scip_trans callback where I get the transformed variables like this:

SCIP_VAR * y_uv_s = NULL;
SCIP_CALL( SCIPgetTransformedVar(scip, y_vars(uv,s), &y_uv_s) );
// Store y_uv_s somewhere.
...
SCIP_CALL( SCIPcaptureVar(scip,y_uv_s) );

This is pretty close to the code in the ProbDataTSP.cpp example.
Something that strikes me as odd:

scip_trans is called twice, once after the presolving, and then again in
the RENS heuristic.
But it seems that in the latter case, scip_trans is not called on the
original problem, but on the transformed
problem, which is also why I end up with variables with names like
"t_t_y_(0,2)_0".
The assertion that fails (see above) fails for the variable with name
"t_y_(0,2)_0", and it thinks that this is an
original variable, which it is obviously not!

If you have any suggestions, I would appreciate to hear them,
otherwise I just wish all of you

merry christmas!

  Daniel


// Store y_uv_s somewhere.
...
SCIP_CALL( SCIPcaptureVar(scip,y_uv_s) );

2011/12/20 Stefan Heinz <heinz at zib.de>

> Hi Daniel,
>
> to get everything ordered.
>
> First Roberts guess w.r.t. the original variables seems to be the
> problem. That means you have to transform the variables form the
> original space into the transformed space. This, however, is not
> possible during the problem creation stage since the transformed problem
> does not exist at that moment. This you have to do in the method
> scip_trans() (in case of C++ Plugin). SCIP calls these methods during
> the transformation stage and gives all plugins the chance to adjust
> their private data for the transformed space.
>
> Second, there is difference between SCIPgetTransformedVar() and
> SCIPvarGetTransVar()
>
> http://scip.zib.de/doc/html/scip_8h.html#ae01de0744cef850ee4971ca3f53aa062
>
> http://scip.zib.de/doc/html/pub__var_8h.html#ad3fb7925b32ab4d248131bb7eed9143d
>
> The method SCIPgetTransformedVar() can handle besides original variables
> also negated variables and some others. Whereas the method
> SCIPvarGetTransVar() assumes that the given variable is an original
> variable (see assert in var.c). I suggest in your case to use
> SCIPgetTransformedVar(). Both methods, however, are only useful if SCIP
> is not in the problem creation stage since at this point in time the
> transformed problem does not exist yet. In case of
> SCIPgetTransformedVar() it is possible to check that since a SCIP
> pointer is at hand in case of SCIPvarGetTransVar() this check is not
> possible since no SCIP pointer is available. This explains the behavior
> you saw.
>
> Third, the basic rule when to use transformed variables and when
> original variables is very basic. During the creation of your problem
> you are creating original variables which means within that stage you
> are working with them (and only with them). During the presolving and
> solving stage you should work with the transformed variables. Using the
> original variables is also possible but has some limitations. I
> *strongly* suggest in all cases to work during the presolving and
> solving stage only with the transformed variables.
>
> Regarding the SCIPgetVarCopy(), I think we can fix the issue such that
> you can give it original variables. Can you test the following fix. Add
> the following two lines
>
>   if( SCIPvarGetStatus(sourcevar) == SCIP_VARSTATUS_ORIGINAL &&
> SCIPisTransformed(sourcescip) )
>       sourcevar = SCIPvarGetTransVar(sourcevar);
>
> in the method SCIPvarGetCopy() after the line:
>
> *sucess = TRUE
>
> and check if it works without transforming the variables. If so that fix
> will be part of the bugfix release 2.1.1.
>
>
> Best and Thanks for testing
> Stefan
>
>
> .
>
> On 12/20/11 12:23, Stefan Vigerske wrote:
> > Hi,
> >
> >> I think I may have found a bug ... or I really don't understand
> something.
> >> ;-)
> >> The "ERROR: cannot call method<SCIPgetTransformedVar>   in problem
> creation
> >> stage" (see below)
> >> disappears when I change
> >>
> >> SCIP_VAR * ty = NULL;
> >> SCIP_CALL( SCIPgetTransformedVar(scip, y_vars(uv,s),&ty) );
> >                                      ^^^^
> >
> > I guess that the scip here has to be sourcescip.
> > You should not pass in the new scip to get the transformed variable for
> > a variable y_vars(uv,s) in the scip that you try to copy.
> >
> >
> >> to
> >>
> >> SCIP_VAR * ty = SCIPvarGetTransVar(y_vars(uv,s));
> >>
> >> Aren't those to calls supposed to be equivalent?
> > SCIPgetTransformedVar does some more checks and also works for negated
> > variables.
> >
> > Stefan
> >
> >>     Daniel
> >>
> >> 2011/12/20 Daniel Karch<karch at math.tu-berlin.de>
> >>
> >>> Wow, that was fast! :-)
> >>>
> >>> Unfortunately, that does not work either:
> >>>
> >>> [src/scip/scip.c:187] ERROR: cannot call method<SCIPgetTransformedVar>
>   in
> >>> problem creation stage
> >>> [src/scip/scip.c:8817] ERROR: Error<-8>   in function call
> >>> [src/ProbDataMinCon.cpp:76] ERROR: Error<-8>   in function call
> >>> [src/objscip/objprobdata.cpp:162] ERROR: Error<-8>   in function call
> >>> [src/scip/prob.c:217] ERROR: Error<-8>   in function call
> >>> [src/scip/scip.c:1068] ERROR: Error<-8>   in function call
> >>> [src/scip/scip.c:1967] ERROR: Error<-8>   in function call
> >>> [src/scip/heur_rens.c:393] ERROR: Error<-8>   in function call
> >>> [src/scip/heur_rens.c:696] ERROR: Error<-8>   in function call
> >>> [src/scip/heur.c:398] ERROR: Error<-8>   in function call
> >>> [src/scip/solve.c:241] ERROR: Error<-8>   in function call
> >>> [src/scip/solve.c:3328] ERROR: Error<-8>   in function call
> >>> [src/scip/solve.c:3879] ERROR: Error<-8>   in function call
> >>> [src/scip/scip.c:7543] ERROR: Error<-8>   in function call
> >>> [src/scip/scipshell.c:135] ERROR: Error<-8>   in function call
> >>> [src/scip/scipshell.c:341] ERROR: Error<-8>   in function call
> >>> [src/cppmain.cpp:85] ERROR: Error<-8>   in function call
> >>> SCIP Error (-8): method cannot be called at this time in solution
> process
> >>>
> >>> Do I also have to implement the scip_trans callback?
> >>>
> >>>     Daniel
> >>>
> >>> P.S.: By the way, I think the documentation does not make it very clear
> >>> when the transformed variables have to be used ...
> >>>
> >>>
> >>>
> >>> 2011/12/20 Robert Schwarz<schwarz at zib.de>
> >>>
> >>>> Hi Daniel
> >>>>
> >>>> On 12/20/2011 11:17 AM, Daniel Karch wrote:
> >>>>> src/scip/scip.c:1422: SCIPcopyVars: Assertion
> >>>> `SCIPgetNIntVars(sourcescip)
> >>>>> + SCIPgetNBinVars(sourcescip)<= SCIPgetNIntVars(targetscip) +
> >>>>> SCIPgetNBinVars(targetscip)&&   SCIPgetNIntVars(targetscip) +
> >>>>> SCIPgetNBinVars(targetscip)<= SCIPgetNIntVars(sourcescip) +
> >>>>> SCIPgetNBinVars(sourcescip) + nfixedbinvars + nfixedintvars' failed.
> >>>>>
> >>>>> I get
> >>>>>
> >>>>> SCIPgetNIntVars(sourcescip) + SCIPgetNBinVars(sourcescip) +
> >>>> nfixedbinvars +
> >>>>> nfixedintvars == 25093
> >>>>>
> >>>>> and
> >>>>>
> >>>>> SCIPgetNIntVars(targetscip) + SCIPgetNBinVars(targetscip) == 27366
> >>>>>
> >>>>> After the presolving, the problem has 2273 binary variables, which is
> >>>>> exactly the difference here.
> >>>>> I figured out that the problem occurs in scip.c, l. 1966:
> >>>>>
> >>>>> /* create problem in the target SCIP and copying the source problem
> >>>> data */
> >>>>> SCIP_CALL( SCIPcopyProb(sourcescip, targetscip, localvarmap,
> >>>> localconsmap,
> >>>>> global, name) );
> >>>>>
> >>>>> /* copy all active variables */
> >>>>> SCIP_CALL( SCIPcopyVars(sourcescip, targetscip, localvarmap,
> >>>> localconsmap,
> >>>>> global) );
> >>>>>
> >>>>> The call to SCIPcopyProb() calls my scip_copy() callback and copies
> all
> >>>> the
> >>>>> variables, and the subsequent call to SCIPcopyVars() copies the
> active
> >>>>> variables *again*.
> >>>>> Now I don't really know what to do. The TSP example is the only one
> I am
> >>>>> aware of that implements the scip_copy() callback in the ProbData
> class,
> >>>>> and I did it just like it is
> >>>>> done there.
> >>>>>
> >>>>> Any suggestions?
> >>>> I just had the same problem. In your copy method of your ProbData
> class,
> >>>> you probably copy the variables of the original problem, whereas the
> >>>> SCIPcopyVars() line copies the variables of the transformed problem.
> >>>> This also explains the difference in cardinality.
> >>>>
> >>>> Otherwise SCIPgetVarCopy() can figure out which variables have already
> >>>> been copied.
> >>>>
> >>>> I suggest you also copy the transformed variables in your probdata,
> >>>> using SCIPgetTransformedVar.
> >>>>
> >>>> Hope that helps.
> >>>>
> >>>> --
> >>>> Robert Schwarz
> >>>> schwarz at zib.de
> >>>>
> >>>>
> >>
> >>
> >> _______________________________________________
> >> Scip mailing list
> >> Scip at zib.de
> >> http://listserv.zib.de/mailman/listinfo/scip
> >
>
> _______________________________________________
> Scip mailing list
> Scip at zib.de
> http://listserv.zib.de/mailman/listinfo/scip
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserv.zib.de/mailman/private/scip/attachments/20111222/456e57fe/attachment.html


More information about the Scip mailing list