From c744faba325f80c822d1227f566b559a98d40c2a Mon Sep 17 00:00:00 2001
From: daveabiy <dawitk27@gmail.com>
Date: Fri, 16 Jul 2021 02:54:24 +0200
Subject: [PATCH] deals with the variable data in the problem, including
 coefficients and space

---
 src/vardata_lagr.cpp | 256 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 256 insertions(+)
 create mode 100644 src/vardata_lagr.cpp

diff --git a/src/vardata_lagr.cpp b/src/vardata_lagr.cpp
new file mode 100644
index 0000000..766c38c
--- /dev/null
+++ b/src/vardata_lagr.cpp
@@ -0,0 +1,256 @@
+/** 
+ * For the next code, we want to find the constraints that are connected with a certain variable, for example x_1_1. We create three for loops, first one is for the variables, for eg. x_1_1.
+ * after that we start a second loop for the constraints, let's say for C1, and we go through all the variables connected with this cons. Third loop will go through the variable in step 2 
+ * one by one and then compares it with the original var, x_1_1. If true(the indexes are the same), the constrait will be saved in the array designated, constraintarray or better name, varconss. 
+ 
+ * The second part of the loop will be to separate the constraints attached with our variable, for example, c1,c2,F1. For this we create a for loop with size equaling to 3(for the ex.)
+ * we create an if condition that checkes if the cons starts with c or F. If c, then we create and allocate it to an array called "slotconstraintarray", else, "VarStartConssarray".
+ * We assure that one variable is only found in one of the start constraints with an assert function. 
+ * All of these will be saved under the vardata!
+*//*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
+
+//#include "probdata_lagr.h"
+#include "vardata_lagr.h"
+#include "probdata_lagr.h"
+#include <chrono>
+
+#include <iostream>
+#include <assert.h>
+struct SCIP_VarData
+{
+   SCIP_VAR*                        var;
+   SCIP_CONS**                      VarConss;
+   int                              nVarConss;
+   SCIP_CONS**                      VarSlotConss;                   /**<contains all slot constraints containing the variable */
+   int                              nVarSlotConss;                 /**<number of slot constraints the variable is occuring in*/  
+   SCIP_Real                        varquotient;
+   int*                              consids;
+   int                               varid;
+};
+
+SCIP_RETCODE vardataDelete(
+   SCIP*                 scip,               /**< SCIP data structure */
+   SCIP_VARDATA**        vardata             /**< vardata to delete */
+   )
+{
+   SCIPfreeBlockMemoryArray(scip, &(*vardata)->consids, (*vardata)->nVarSlotConss);
+   SCIPfreeBlockMemory(scip, vardata);
+
+   return SCIP_OKAY;
+}
+
+/** frees user data of variable */
+SCIP_RETCODE vardatafree(
+   SCIP*                 scip,               /**< SCIP data structure */
+   SCIP_VARDATA**        vardata             /**< vardata to delete */
+   )
+{
+   assert(scip != NULL);
+   assert(vardata != NULL);
+   assert(*vardata!=NULL);
+
+  
+   if((*vardata)->VarSlotConss != NULL)
+   {
+      SCIPfreeBlockMemoryArray(scip, &(*vardata)->VarSlotConss, (*vardata)->nVarSlotConss);
+   }
+   SCIPfreeBlockMemory(scip, vardata);
+   
+
+   return SCIP_OKAY;
+}
+
+
+
+/** gets the slot conss the var is occuring*/
+SCIP_CONS** SCIPvardataGetSlotConss(
+	SCIP_VARDATA* vardata     /**< variable data */
+   )
+ {
+    return vardata->VarSlotConss;
+ }
+
+
+/** gets the number of slot conss the var is occuring in*/
+int SCIPvardataGetnVarSlotConss(
+	SCIP_VARDATA* vardata     /**< variable data */
+)
+ {
+    return vardata->nVarSlotConss;
+ }
+
+int* SCIPvardataGetconsids(
+	SCIP_VARDATA* vardata     /**< variable data */
+)
+ {
+    return vardata->consids;
+ }
+
+int SCIPvardataGetVarID(
+	SCIP_VARDATA* vardata     /**< variable data */
+)
+ {
+    return vardata->varid;
+ }
+
+ 
+/** we add the quotient of each variable, which is equal to: (weight of variable)/(nVarSlotConss)     */
+SCIP_Real SCIPvarGetQuotient(SCIP_VARDATA* vardata)
+{
+
+   return vardata->varquotient;
+}
+
+SCIP_RETCODE SCIPvardataCreateLagrangian(
+   SCIP*                            scip,                          /**< SCIP data structure*/
+   SCIP_VARDATA*                   vardata,                       /**<pointer to the vardata*/
+   SCIP_VAR**                       var,
+   int                            nSlotConss,
+   int                              v
+)
+{
+
+   SCIP_CONS** conss = SCIPgetConss(scip);
+   // int nconss = SCIPgetNConss(scip);
+   int nVarSlotConss = 0;
+   int varid;
+   int* consids;
+   
+   // SCIP_CONS**                      VarSlotConss,                  /**< all slot constraints containing the variable */
+   // int                              nVarSlotConss,                 /**<number of slot constraints the variable is occuring in*/
+   
+   int varindex = SCIPvarGetIndex(*var);                                    /* (2) */
+   assert(varindex!= NULL);
+
+   SCIP_Bool success;
+   SCIP_Real varquotient;
+   // printf("%s {",SCIPvarGetName(*var));                                                      /* (5) */
+
+
+   SCIP_CALL(SCIPallocBufferArray(scip,&consids,nSlotConss));
+  
+   SCIP_VAR** varbuffer;
+
+   for (int r = 0; r < nSlotConss; ++r)
+   {
+      SCIP_CONS* cons = conss[r];
+      if(SCIPconsGetLhs(scip,cons,&success)==-SCIPinfinity(scip))
+      {
+         int nconsvars;
+      /** request number of variables of constraint [c] */
+      
+         SCIP_CALL(SCIPgetConsNVars(scip, cons, &nconsvars, &success));            /* (6) */
+         if (!success)
+         {
+            abort();
+         }
+         //cout<<""<<nconsvars<<"v ";
+         /** allocate memory for the varbuffer arrays of the size of "nconsvars" */
+         SCIP_CALL(SCIPallocBufferArray(scip, &varbuffer, nconsvars));             /* (7) */
+         /** collect constraint variables in array "varbuffer" */
+         SCIP_CALL(SCIPgetConsVars(scip, cons, varbuffer, nconsvars, &success));
+         /** If no success, abort process */
+         if (!success)
+            abort();  
+         
+         /** loop over constraint variables and compare varindices */
+         for (int j = 0; j < nconsvars; ++j)                                            /* (8) */
+         {
+            SCIP_VAR* varx = varbuffer[j];
+            int varbufindex = SCIPvarGetIndex(varx);
+            assert(varbufindex != NULL);
+            
+            /** if var[i] is in cons[c], write conspointer in VarConss and increase nVarConsscounter */
+            if (varindex == varbufindex)                                           /* (9) */
+            {
+               
+               // VarSlotConss[nVarSlotConss] = cons;
+               consids[nVarSlotConss]=r;
+               nVarSlotConss++;
+               // printf("%s,",SCIPconsGetName(cons));
+               
+
+            }
+         }
+      }
+      
+   }
+   
+   if(nVarSlotConss!=0)
+   {
+      varquotient = SCIPvarGetObj(*var)/nVarSlotConss;
+      // printf("(%f)",varquotient);
+
+   }
+   else if(nVarSlotConss ==0)
+   {
+      varquotient =100000000000;
+      //printf("/%f\n",varquotient);
+   }
+
+   varid = v;
+   /** allocate memory for vardata*/
+   SCIP_CALL(SCIPallocBlockMemory(scip , &vardata));     
+   SCIP_CALL(SCIPduplicateBlockMemoryArray(scip, &(vardata->consids), consids, nVarSlotConss));
+   vardata->nVarSlotConss = nVarSlotConss;  /**copy nVarConss to VarData */
+   vardata->varquotient = varquotient;
+   vardata->varid = varid;
+   /**set the variable data to the variable*/
+   SCIPvarSetData(*var,vardata);  
+   // SCIPfreeBufferArray(scip,VarSlotConss);
+   SCIPfreeBufferArray(scip,&consids);
+   // printf("*");
+  
+   return SCIP_OKAY;
+}
+
+
+/*******************************************************************************************************/
+/* The reformulation of the problem can be written as follows                                          */
+//*>>>>>>>>>>>>>>>>>> min sum { (w[i]+sum{dual[j]})}x[i]-sum{dual[r]} <<<<<<<<<<<<                     */
+/*where i is nvars, j is nVarSlotConss, and r is nSlotConss for our case *******************************/
+/****************************************************************************************************************/
+/* The following function will add the following to the obj(weight) of the variable,                            */
+//*  the obj(weight) of var + the sum of the dualmultipliers of bad constraints which contains this variable    */
+/****************************************************************************************************************/
+SCIP_RETCODE SCIPvarchangeDuals(SCIP* relaxscip,SCIP_VAR*** vars, SCIP_Real* dualmultipliers, SCIP_Real* origobj)
+{
+
+   SCIP_CONS** conss = SCIPgetConss(relaxscip);
+   int nconss = SCIPgetNConss(relaxscip);
+   SCIP_VARDATA* vardata;
+   int nvars = SCIPgetNVars(relaxscip);
+
+   for(int v = 0; v<nvars; ++v)
+   {
+      SCIPfreeTransform(relaxscip);
+      SCIP_VAR* var = (*vars)[v];  
+      SCIP_Real addonvar = 0;
+
+      SCIPchgVarObj(relaxscip,var,origobj[v]);
+
+      vardata = SCIPvarGetData(var);
+      int* consids;
+      
+      consids = SCIPvardataGetconsids(vardata); 
+      //prinf("\n%s(",SCIPvarGetName(var));
+
+      for(int j= 0; j<SCIPvardataGetnVarSlotConss(vardata);++j)
+      {
+         // printf("%d ",SCIPvardataGetconsids(vardata)[j]);
+         int consid = consids[j];
+         
+         SCIP_CONS* varcons = conss[consid];
+         //prinf(" (%s with %f) ",SCIPconsGetName(varcons), dualmultipliers[consid]);
+         addonvar += dualmultipliers[consid];
+         
+         
+         
+      }
+      
+      SCIP_CALL(SCIPaddVarObj(relaxscip,var,addonvar));
+      //prinf("**(added %f to %f = %f)**\t",addonvar, origobj[v], SCIPvarGetObj(var));
+      // SCIP_CALL(SCIPaddVarObj(relaxscip,var,addonvar));
+   }
+   return SCIP_OKAY;
+}
-- 
GitLab