[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