0

I am trying to solve a very simple TSP problem but the TSP example of SCIP is a bit intimidating.

I just want to add simple Lazy constraints like how GuRoBi does.

I might need some help in understanding what is happening at some places.

I assume I do not have to implement SCIP_DECL_CONSSEPALP SCIP_DECL_CONSENFOLP and SCIP_DECL_CONSENFOPS. I only have to implement a simple cycle detection function and add that as a cut.

If I understand correctly, I can write the function do the cycle detection in SCIP_DECL_CONSCHECK but I am unsure how it is actually working.

assert(result != NULL);
   *result = SCIP_FEASIBLE;

   for( int i = 0; i < nconss; ++i )
   {
      SCIP_CONSDATA* consdata;
      GRAPH* graph;
      SCIP_Bool found;

      assert(conss != NULL);
      assert(conss[i] != NULL);
      consdata = SCIPconsGetData(conss[i]);
      assert(consdata != NULL);
      graph = consdata->graph;
      assert(graph != NULL);

      // if a subtour is found, the solution must be infeasible
      found = findSubtour(scip, graph, sol);
      if( found )
      {
         *result = SCIP_INFEASIBLE;
         if( printreason )
         {
            SCIP_CALL( SCIPprintCons(scip, conss[i], NULL) );
            SCIPinfoMessage(scip, NULL, "violation: graph has a subtour\n");
         }
      }
   }

   return SCIP_OKAY;

If I only have a single constraint handler, should I still use nconss? What exactly happens after I find a subtour? Which function is called after we set *result to SCIP_INFEASIBLE?

And how can I pass the subtour (the vertices that are in the tour) I found in SCIP_DECL_CONSCHECK to that function so that I do not have to find the cycle again and add the actual cut?

Morpheus
  • 3,285
  • 4
  • 27
  • 57

1 Answers1

2

You actually need to implement two callbacks. The SCIP_DECL_CONSCHECK AND the SCIP_DECL_CONSENFOLP.

In the checking callback you only need to detect if a subtour is found and if that is the case, to set the result to SCIP_INFEASIBLE (as you have done). You do not have to use nconss since your subtour constraint handler does not have any constraints.

In the enforcement callback SCIP_DECL_CONSENFOLP you have to actually resolve these infeasibilities by adding a new subtour elimination constraint.

If you want to learn more about how these SCIP callbacks work, you can listen to my talk from last years CO@Work summer school (the running example is TSP) on youtube. Also the exercise Programming plugins from the same day is an implementation of the TSP in PySCIPopt, to which you can find the solution on the Co@Work webpage.

Leon
  • 1,588
  • 1
  • 7
  • 16
  • Thanks a lot Leon. I will definitely give the talk a listen. this link (http://listserv.zib.de/pipermail/scip/2013-April/001412.html) was what I was going by and it seems like I assumed sepalp and enfolp only work when there is an LP solution. Thanks. – Morpheus Jan 13 '21 at 13:21
  • I was planning to set the check priority flag to -1 and hence, the constraint handler will only be called when the integer solution is available. and then I assume I jut have to call `sepaSubtour` from enfolp? – Morpheus Jan 13 '21 at 13:29
  • 1
    Yes to calling sepaSubtour from enfolp and setting the priority to something negative. I think the misunderstanding you had is: The solutions you enforce on are still LP solutions in the sense that they come from the LP (even if they are all integer feasible since you only run with negative priority) – Leon Jan 14 '21 at 10:34