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

Stefan Heinz heinz at zib.de
Tue Dec 20 13:21:48 MET 2011


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
>



More information about the Scip mailing list