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

Stefan Vigerske stefan at math.hu-berlin.de
Thu Dec 22 14:11:44 MET 2011


Hi,

> 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

Usually, this is caused by a forgotten release of a variable in the 
transformed problem (here the transformed problem in the copy).
Check that you release all variables that you capture.

> 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".

RENS copies the transformed problem into a new SCIP instance.
That new instance is then transformed again, that's where the second 
call comes from.

> 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!

It's confusing, but it's an original variable in the copy.
Since the copy was created from a transformed problem, variable names 
start with "t_". Transformation of the copy then gives variable names 
that start with "t_t_".

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

Find out whether your code also releases variable t_t_y_(0,2)_0, if it 
captures it.

Stefan

>
> 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
>>
>
>
>
> _______________________________________________
> Scip mailing list
> Scip at zib.de
> http://listserv.zib.de/mailman/listinfo/scip


-- 
Stefan Vigerske
Humboldt University Berlin, Numerical Mathematics
http://www.math.hu-berlin.de/~stefan


More information about the Scip mailing list