├── .gitignore ├── ACO.cpp ├── ACO.h ├── BeamSearch.cpp ├── BeamSearch.h ├── Benders.cpp ├── Benders.h ├── ConstructHeu.cpp ├── ConstructHeu.h ├── Controller.cpp ├── Controller.h ├── Corridor.cpp ├── Corridor.h ├── Ejection.cpp ├── Ejection.h ├── ForwardBackward.cpp ├── ForwardBackward.h ├── GAP.cpp ├── GAP.h ├── GAPVS ├── GAP.lp ├── GAPVS.exe ├── GAPVS.sln ├── GAPVS.vcxproj ├── GAPVS.vcxproj.filters ├── GAPVS128.vcxproj ├── GAPVS129.vcxproj ├── GAPdual.lp ├── GAPmaster.lp ├── Release │ ├── GAPVS.iobj │ ├── GAPVS.ipdb │ └── GAPVS.tlog │ │ ├── CL.command.1.tlog │ │ ├── CL.read.1.tlog │ │ ├── CL.write.1.tlog │ │ ├── GAPVS.lastbuildstate │ │ ├── GAPVS.write.1u.tlog │ │ ├── link.command.1.tlog │ │ ├── link.read.1.tlog │ │ └── link.write.1.tlog ├── config.json └── x64 │ └── Release │ └── GAPVS.tlog │ ├── CL.command.1.tlog │ ├── CL.read.1.tlog │ ├── CL.write.1.tlog │ ├── GAPVS.lastbuildstate │ └── unsuccessfulbuild ├── GAPVSC ├── cplex1263.dll ├── cplex1263.lib ├── cplex1290.dll ├── cplex1290.lib ├── makefile └── matheuristics.code-workspace ├── GeneticAlgorithm.cpp ├── GeneticAlgorithm.h ├── Kernel.cpp ├── Kernel.h ├── Lagrangian.cpp ├── Lagrangian.h ├── LocBranching.cpp ├── LocBranching.h ├── LocalSearch.cpp ├── LocalSearch.h ├── LowerBound.cpp ├── LowerBound.h ├── MIPCplex.cpp ├── MIPCplex.h ├── MTHG.cpp ├── MTHG.h ├── MetaLocalSearch.cpp ├── MetaLocalSearch.h ├── Persistence.cpp ├── Persistence.h ├── README.md ├── Rins.cpp ├── Rins.h ├── SS.cpp ├── SS.h ├── SimAnnealing.cpp ├── SimAnnealing.h ├── TabuSearch.cpp ├── TabuSearch.h ├── VLSN.cpp ├── VLSN.h ├── config.h ├── cpxconst.h ├── fileList.txt ├── json.cpp ├── json.h └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | *.tlog 12 | *.idb 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | GAPVS/[Dd]ebug/ 19 | GAPVS/[Dd]ebugPublic/ 20 | GAPVS/[Rr]elease/ 21 | GAPVS/[Rr]eleases/ 22 | GAPVS/x64/ 23 | GAPVS/x86/ 24 | GAPVS/bld/ 25 | GAPVS/[Bb]in/ 26 | GAPVS/[Oo]bj/ 27 | GAPVS/[Ll]og/ 28 | .vscode/ 29 | x64/ 30 | [Dd]ebug/ 31 | [Rr]elease/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUNIT 46 | *.VisualState.xml 47 | TestResult.xml 48 | 49 | # Build Results of an ATL Project 50 | [Dd]ebugPS/ 51 | [Rr]eleasePS/ 52 | dlldata.c 53 | 54 | # Benchmark Results 55 | BenchmarkDotNet.Artifacts/ 56 | 57 | # .NET Core 58 | project.lock.json 59 | project.fragment.lock.json 60 | artifacts/ 61 | **/Properties/launchSettings.json 62 | 63 | # StyleCop 64 | StyleCopReport.xml 65 | 66 | # Files built by Visual Studio 67 | *_i.c 68 | *_p.c 69 | *_i.h 70 | *.ilk 71 | *.meta 72 | *.obj 73 | *.pch 74 | *.pdb 75 | *.pgc 76 | *.pgd 77 | *.rsp 78 | *.sbr 79 | *.tlb 80 | *.tli 81 | *.tlh 82 | *.tmp 83 | *.tmp_proj 84 | *.log 85 | *.vspscc 86 | *.vssscc 87 | .builds 88 | *.pidb 89 | *.svclog 90 | *.scc 91 | *.tlog 92 | *.idb 93 | 94 | # Chutzpah Test files 95 | _Chutzpah* 96 | 97 | # Visual C++ cache files 98 | ipch/ 99 | *.aps 100 | *.ncb 101 | *.opendb 102 | *.opensdf 103 | *.sdf 104 | *.cachefile 105 | *.VC.db 106 | *.VC.VC.opendb 107 | 108 | # Visual Studio profiler 109 | *.psess 110 | *.vsp 111 | *.vspx 112 | *.sap 113 | 114 | # Visual Studio Trace Files 115 | *.e2e 116 | 117 | # TFS 2012 Local Workspace 118 | $tf/ 119 | 120 | # Guidance Automation Toolkit 121 | *.gpState 122 | 123 | # ReSharper is a .NET coding add-in 124 | _ReSharper*/ 125 | *.[Rr]e[Ss]harper 126 | *.DotSettings.user 127 | 128 | # JustCode is a .NET coding add-in 129 | .JustCode 130 | 131 | # TeamCity is a build add-in 132 | _TeamCity* 133 | 134 | # DotCover is a Code Coverage Tool 135 | *.dotCover 136 | 137 | # AxoCover is a Code Coverage Tool 138 | .axoCover/* 139 | !.axoCover/settings.json 140 | 141 | # Visual Studio code coverage results 142 | *.coverage 143 | *.coveragexml 144 | 145 | # NCrunch 146 | _NCrunch_* 147 | .*crunch*.local.xml 148 | nCrunchTemp_* 149 | 150 | # MightyMoose 151 | *.mm.* 152 | AutoTest.Net/ 153 | 154 | # Web workbench (sass) 155 | .sass-cache/ 156 | 157 | # Installshield output folder 158 | [Ee]xpress/ 159 | 160 | # DocProject is a documentation generator add-in 161 | DocProject/buildhelp/ 162 | DocProject/Help/*.HxT 163 | DocProject/Help/*.HxC 164 | DocProject/Help/*.hhc 165 | DocProject/Help/*.hhk 166 | DocProject/Help/*.hhp 167 | DocProject/Help/Html2 168 | DocProject/Help/html 169 | 170 | # Click-Once directory 171 | publish/ 172 | 173 | # Publish Web Output 174 | *.[Pp]ublish.xml 175 | *.azurePubxml 176 | # Note: Comment the next line if you want to checkin your web deploy settings, 177 | # but database connection strings (with potential passwords) will be unencrypted 178 | *.pubxml 179 | *.publishproj 180 | 181 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 182 | # checkin your Azure Web App publish settings, but sensitive information contained 183 | # in these scripts will be unencrypted 184 | PublishScripts/ 185 | 186 | # NuGet Packages 187 | *.nupkg 188 | # The packages folder can be ignored because of Package Restore 189 | **/[Pp]ackages/* 190 | # except build/, which is used as an MSBuild target. 191 | !**/[Pp]ackages/build/ 192 | # Uncomment if necessary however generally it will be regenerated when needed 193 | #!**/[Pp]ackages/repositories.config 194 | # NuGet v3's project.json files produces more ignorable files 195 | *.nuget.props 196 | *.nuget.targets 197 | 198 | # Microsoft Azure Build Output 199 | csx/ 200 | *.build.csdef 201 | 202 | # Microsoft Azure Emulator 203 | ecf/ 204 | rcf/ 205 | 206 | # Windows Store app package directories and files 207 | AppPackages/ 208 | BundleArtifacts/ 209 | Package.StoreAssociation.xml 210 | _pkginfo.txt 211 | *.appx 212 | 213 | # Visual Studio cache files 214 | # files ending in .cache can be ignored 215 | *.[Cc]ache 216 | # but keep track of directories ending in .cache 217 | !*.[Cc]ache/ 218 | 219 | # Others 220 | ClientBin/ 221 | ~$* 222 | *~ 223 | *.dbmdl 224 | *.dbproj.schemaview 225 | *.jfm 226 | *.pfx 227 | *.publishsettings 228 | orleans.codegen.cs 229 | 230 | # Including strong name files can present a security risk 231 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 232 | #*.snk 233 | 234 | # Since there are multiple workflows, uncomment next line to ignore bower_components 235 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 236 | #bower_components/ 237 | 238 | # RIA/Silverlight projects 239 | Generated_Code/ 240 | 241 | # Backup & report files from converting an old project file 242 | # to a newer Visual Studio version. Backup files are not needed, 243 | # because we have git ;-) 244 | _UpgradeReport_Files/ 245 | Backup*/ 246 | UpgradeLog*.XML 247 | UpgradeLog*.htm 248 | ServiceFabricBackup/ 249 | 250 | # SQL Server files 251 | *.mdf 252 | *.ldf 253 | *.ndf 254 | 255 | # Business Intelligence projects 256 | *.rdl.data 257 | *.bim.layout 258 | *.bim_*.settings 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # TypeScript v1 declaration files 271 | typings/ 272 | 273 | # Visual Studio 6 build log 274 | *.plg 275 | 276 | # Visual Studio 6 workspace options file 277 | *.opt 278 | 279 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 280 | *.vbw 281 | 282 | # Visual Studio LightSwitch build output 283 | **/*.HTMLClient/GeneratedArtifacts 284 | **/*.DesktopClient/GeneratedArtifacts 285 | **/*.DesktopClient/ModelManifest.xml 286 | **/*.Server/GeneratedArtifacts 287 | **/*.Server/ModelManifest.xml 288 | _Pvt_Extensions 289 | 290 | # Paket dependency manager 291 | .paket/paket.exe 292 | paket-files/ 293 | 294 | # FAKE - F# Make 295 | .fake/ 296 | 297 | # JetBrains Rider 298 | .idea/ 299 | *.sln.iml 300 | 301 | # CodeRush 302 | .cr/ 303 | 304 | # Python Tools for Visual Studio (PTVS) 305 | __pycache__/ 306 | *.pyc 307 | 308 | # Cake - Uncomment if you are using it 309 | # tools/** 310 | # !tools/packages.config 311 | 312 | # Tabs Studio 313 | *.tss 314 | 315 | # Telerik's JustMock configuration file 316 | *.jmconfig 317 | 318 | # BizTalk build output 319 | *.btp.cs 320 | *.btm.cs 321 | *.odx.cs 322 | *.xsd.cs 323 | 324 | # OpenCover UI analysis results 325 | OpenCover/ 326 | 327 | # Azure Stream Analytics local run output 328 | ASALocalRun/ 329 | 330 | # MSBuild Binary and Structured Log 331 | *.binlog -------------------------------------------------------------------------------- /ACO.cpp: -------------------------------------------------------------------------------- 1 | #include "ACO.h" 2 | 3 | ACO::ACO(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | ACO::~ACO() 15 | { 16 | //dtor 17 | } 18 | 19 | int ACO::antColony(int** c, int maxiter, int numpop, double alpha) 20 | { int z=0; 21 | int i,j,k,iter,index,cnt,numsol=0; 22 | double lb=0, lbMove,avgtau=0,zavg=0; 23 | vector< vector > pop(numpop); 24 | vector> deltaTau; 25 | vector moveProb(m),zpop(numpop); 26 | 27 | // Lower bound computation, linear bound 28 | int numRows, numCols, numNZrow, statusMIP; 29 | numRows = n + m; // num of constraints 30 | numCols = n * m; // num of variables 31 | numNZrow = n * m; // maximum num of nonzero values in a row 32 | MIPCplex* CPX = new MIPCplex(numRows, numCols, numNZrow); 33 | CPX->GAP = GAP; 34 | CPX->allocateMIP(false); // verbose output 35 | statusMIP = CPXsetintparam(CPX->env, CPXPARAM_ScreenOutput, CPX_OFF); 36 | 37 | statusMIP = CPX->solveMIP(false, false); // LP of whole instance 38 | if (statusMIP == 0) 39 | { lb = CPX->objval; 40 | cout << "Linear bound: " << lb << endl; 41 | if (n * m < 101) // print LP if instance is small 42 | { 43 | cout << " - Solution: " << endl; 44 | for (i = 0; i < m; ++i) 45 | { cout << " " << i << ": "; 46 | for (j = 0; j < n; ++j) 47 | cout << CPX->x[i * n + j] << "\t"; 48 | cout << endl; 49 | } 50 | } 51 | } 52 | else 53 | lb = 0; 54 | 55 | // trail initialization to lb 56 | tau.assign(m, vector(n, 0)); 57 | for (i = 0; i < m; ++i) 58 | for (j = 0; j < n; ++j) 59 | { tau[i][j] = CPX->x[i * n + j]; 60 | avgtau += tau[i][j]/(m*n); 61 | } 62 | vector zlast(n,lb); 63 | 64 | // initialize empty solutions 65 | pop.assign(numpop, vector (n,-1)); 66 | 67 | cout << "Population initialized, starting search" << endl; 68 | for (iter = 0; iter < maxiter; iter++) // termination condition on num iterations 69 | { if(iter%1 == 0) 70 | cout << "====== iteration " << iter << " zub = " << zub << endl; 71 | 72 | // for each ant 73 | for (k = 0; k < numpop; k++) 74 | { zpop[k] = -1; 75 | vector sol (n,-1); 76 | for (j = 0; j < n; j++) // for each client to assign 77 | { 78 | if (j > 0 && sol[j-1] == -1) // infeasible partial solution 79 | { sol[j] = -1; 80 | continue; 81 | } 82 | 83 | cnt = j+1; 84 | vector indices(cnt); 85 | vector lu(cnt); 86 | vector bd(cnt); 87 | 88 | for (int j1 = 0; j1 < j; j1++) // partial solution 89 | { indices[j1] = sol[j1] * n + j1; 90 | lu[j1] = 'B'; 91 | bd[j1] = 1.0; 92 | } 93 | 94 | for (i = 0; i < m; i++) // for each server it can be assigned to 95 | { 96 | indices[j] = i * n + j; 97 | lu[j] = 'L'; 98 | bd[j] = 1.0; 99 | statusMIP = CPXchgbds(CPX->env, CPX->lp, cnt, &indices[0], &lu[0], &bd[0]); 100 | statusMIP = CPX->solveMIP(false, false); // LP of partial solution 101 | if(statusMIP) 102 | { moveProb[i] = 0; 103 | cout << "Infeasible choice" << endl; 104 | } 105 | else 106 | { lbMove = CPX->objval; 107 | moveProb[i] = alpha*tau[i][j] + (1-alpha)*1/(1+lbMove - lb); 108 | cout << "lbmove = " << lbMove << " moveprob " << moveProb[i] << endl; 109 | } 110 | bd[j] = 0.0; // change back to free status 111 | statusMIP = CPXchgbds(CPX->env, CPX->lp, cnt, &indices[0], &lu[0], &bd[0]); 112 | } 113 | 114 | index = montecarlo(moveProb); 115 | if (index < m) 116 | { cout << "j= " << j <<" chosen i= " << index << endl; 117 | sol[j] = index; 118 | } 119 | else 120 | { cout << "infeasible partial solution" << endl; 121 | sol[j] = -1; // infeasible partial solution 122 | zpop[k] = -1; 123 | } 124 | 125 | // reset partial solution 126 | cnt = j; 127 | indices.resize(cnt); // which var 128 | lu.resize(cnt); // lower limit 129 | bd.resize(cnt); // new bound 130 | 131 | for (int j1 = 0; j1 < j; j1++) 132 | { indices[j1] = sol[j1] * n + j1; 133 | lu[j1] = 'L'; 134 | bd[j1] = 0.0; 135 | } 136 | statusMIP = CPXchgbds(CPX->env, CPX->lp, cnt, &indices[0], &lu[0], &bd[0]); 137 | } 138 | int z = GAP->checkSol(sol); 139 | if(z(n, 0)); 157 | zavg=0; 158 | for(j=0;j=0) // if feasible solution 162 | for(j=0;j= 0 ? tau[i][j] : 0); 170 | } 171 | } 172 | 173 | double zcheck = 0; 174 | zcheck = GAP->checkSol(solbest); 175 | if (abs(zcheck - zub) > GAP->EPS) 176 | { cout << "[ANTS] Detected inconsistency" << endl; 177 | z = INT_MAX; 178 | } 179 | else 180 | cout << "zcheck " << zcheck << endl; 181 | cout << "ANTS zub= " << zub << endl; 182 | 183 | if(CPX != NULL) delete CPX; 184 | return zub; 185 | } 186 | 187 | int ACO::montecarlo(vector& v) 188 | { double sum=0; 189 | unsigned int i; 190 | 191 | for(i=0;i= f) break; 200 | } 201 | return i; 202 | } 203 | 204 | 205 | -------------------------------------------------------------------------------- /ACO.h: -------------------------------------------------------------------------------- 1 | #ifndef ACO_H 2 | #define ACO_H 3 | #include "GAP.h" 4 | #include "MIPCplex.h" 5 | #include 6 | 7 | class ACO 8 | { 9 | public: 10 | GeneralizedAssignemnt* GAP; 11 | 12 | ACO(GeneralizedAssignemnt*, int&); 13 | ~ACO(); 14 | int antColony(int**, int maxiter, int numpop, double alpha); 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | 23 | vector> tau,eta; 24 | 25 | // private functions 26 | int montecarlo(vector& v); 27 | }; 28 | 29 | #endif // ACO_H 30 | -------------------------------------------------------------------------------- /BeamSearch.cpp: -------------------------------------------------------------------------------- 1 | #include "BeamSearch.h" 2 | 3 | BeamSearch::BeamSearch(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | isVerbose = false; 13 | } 14 | 15 | BeamSearch::~BeamSearch() 16 | { 17 | //dtor 18 | } 19 | 20 | int BeamSearch::beamSearch(int** c, int delta, int maxNodes, bool fVerbose) 21 | { int i,j,jlev,k,z; 22 | int currNode,newNodes,openNodes,numExp; 23 | 24 | vector regrets(n),capleft(m); 25 | vector indCost(n); // index of order of expansion of the clients 26 | auto compRegr = [®rets](int a, int b){ return regrets[a] > regrets[b]; }; // DESC order 27 | 28 | if(GAP->n == NULL) 29 | { cout << "Instance undefined. Exiting" << endl; 30 | return INT_MAX; 31 | } 32 | isVerbose = fVerbose; 33 | 34 | for(j=0;j()); 36 | fList.push_back(list()); 37 | } 38 | 39 | node root; 40 | root.z = 0; 41 | root.dad = 0; 42 | root.server = -1; 43 | root.capused.resize(m); 44 | for(i=0;icap[i]; 50 | computeRegrets(c,n,m,regrets); 51 | 52 | for(j=0;j0;k++) 68 | { currNode = fList[jlev].front(); // gets the first element 69 | if(jlev < n && stack[currNode].z < zub) 70 | { j = (jlev == n-1 ? -1 : indCost[jlev+1]); // client order by regrets 71 | numExp = expandNode(c, j, jlev, currNode, indCost); 72 | openNodes += numExp; 73 | newNodes += numExp; 74 | } 75 | if(indLastNode > maxNodes) goto end; // node limit reached 76 | fTree[jlev].push_back(currNode); // append to list of expanded nodes 77 | fList[jlev].pop_front(); // remove from list of nodes to expand 78 | openNodes--; 79 | } 80 | if(isVerbose) 81 | cout << "Level " << jlev << " expanded " << k << " new nodes " << newNodes << " open nodes " << openNodes << " tot nodes "<< indLastNode << endl; 82 | if(indLastNode % 1000 < 10) 83 | cout << "Nodes " << indLastNode << " open " << openNodes << " zub " << zub << endl; 84 | } 85 | if(openNodes > 0) goto loop; // should be unneeded, but just in case 86 | 87 | end: 88 | if(abs(GAP->checkSol(solbest)-zub) > GAP->EPS) 89 | { cout << "[beamSearch]: Error, solution cost mismatch" << endl; 90 | z = INT_MAX; 91 | } 92 | else 93 | cout << "Construction terminated. zub = " << zub << endl; 94 | return zub; 95 | } 96 | 97 | // c: costs; j: current client; jlev; current tree level; corrNode: node currently expanded (will be father) 98 | int BeamSearch::expandNode(int** c, int j, int jlev, int currNode, vector indCost) 99 | { int i,ii,numNewNodes=0,z=-1; 100 | vector cost(m),indReq(m); 101 | auto compCost = [&cost](int a, int b){ return cost[a] < cost[b]; }; // ASC order 102 | 103 | if(j<0) // reached complete solutions 104 | { if(stack[currNode].z < zub) 105 | z=readSolution(currNode,indCost); 106 | goto end; 107 | } 108 | 109 | // cost of expansions 110 | for(i=0;ic[i][j]; 112 | indReq[i] = i; 113 | } 114 | std::sort(indReq.begin(), indReq.end(), compCost); 115 | 116 | // expansion of a node 117 | ii = numNewNodes = 0; 118 | while(iireq[i][j]) <= GAP->cap[i] && 122 | (stack[currNode].z + GAP->c[i][j]) < zub) 123 | { 124 | node newNode; 125 | for(int ii=0;iireq[i][j]; 127 | newNode.dad = currNode; 128 | newNode.server = i; 129 | newNode.z = stack[currNode].z + GAP->c[i][j]; 130 | stack.push_back(newNode); 131 | indLastNode++; 132 | insertInOrder(fList[jlev+1], indLastNode); // inserts the index of the node in the level list 133 | numNewNodes++; 134 | } 135 | ii++; 136 | } 137 | 138 | end: 139 | return numNewNodes; // new nodes opened at the level 140 | } 141 | 142 | // level: level where to insert; elem: element to insert (key: node cost) 143 | int BeamSearch::insertInOrder(list & lst, int elem) 144 | { int res = 0; 145 | list::iterator it; 146 | 147 | if(lst.size() == 0) 148 | lst.push_back(elem); 149 | else 150 | { it = lst.begin(); 151 | while(it != lst.end() && stack[*it].z < stack[elem].z) 152 | ++it; 153 | lst.insert(it,elem); 154 | } 155 | return res; 156 | } 157 | 158 | // reads the solutions from the last line of the tree 159 | int BeamSearch::readSolution(int currNode, vector indCost) 160 | { int res = 0,j,jlev,solNode; 161 | 162 | if(stack[currNode].z < zub) 163 | { zub = stack[currNode].z; 164 | cout << "New zub: " << zub << endl; 165 | // reconstruction of the solution 166 | solNode = currNode; 167 | jlev = n - 1; 168 | while(stack[solNode].server > -1) 169 | { j = indCost[jlev]; 170 | sol[j] = solbest[j] = stack[solNode].server; 171 | if(isVerbose) 172 | cout << "node " << solNode << " j " << j << " i " << sol[j] << " c " << GAP->c[sol[j]][j] << " z " << stack[solNode].z << endl; 173 | solNode = stack[solNode].dad; 174 | jlev--; 175 | } 176 | } 177 | 178 | return res; 179 | } 180 | 181 | // finds the next node to expand 182 | int BeamSearch::findNextNode(int jlev, int newNodes, int openNodes) 183 | { int jmin; 184 | 185 | if(newNodes>0) // if there were expansions, go on 186 | jlev++; 187 | else // find the highest level with unexpanded nodes 188 | { for(jmin=0;jmin0) 190 | break; 191 | jlev = jmin; 192 | } 193 | return jlev; 194 | } -------------------------------------------------------------------------------- /BeamSearch.h: -------------------------------------------------------------------------------- 1 | #ifndef BEAM_H 2 | #define BEAM_H 3 | #include "GAP.h" 4 | #include 5 | #include // std::copy 6 | 7 | class BeamSearch 8 | { 9 | public: 10 | GeneralizedAssignemnt* GAP; 11 | 12 | BeamSearch(GeneralizedAssignemnt*, int&); 13 | ~BeamSearch(); 14 | int beamSearch(int** c, int delta, int maxNodes, bool fVerbose); // not nice names with small and big cap, isn't it? 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | bool isVerbose; 23 | 24 | // the state of each partial solution 25 | struct node 26 | { int z; // cost of the partial soluton 27 | int server; // who the client is assigned to 28 | int dad; // which sol was expanded into this 29 | vector capused; // array of used capacities 30 | }; 31 | 32 | vector stack; // stack all nodes expanded during search 33 | vector> fTree; // forward tree, one list for each level / customer 34 | vector> fList; // the list of still unexpanded nodes at each level of the forward tree 35 | 36 | int indLastNode; // aka stack.size(). just it 37 | 38 | int expandNode(int** c, int j, int jlev, int currNode, vector indCost); 39 | int insertInOrder(list & lst, int ind); // insert a stack index in a list, ordered on a key 40 | int readSolution(int currNode, vector indCost); // reads the solutions from the last line of the table 41 | int findNextNode(int jlev, int newNodes, int openNodes); // finds the next node to expand 42 | }; 43 | 44 | #endif // BEAM_H 45 | -------------------------------------------------------------------------------- /Benders.cpp: -------------------------------------------------------------------------------- 1 | #include "Benders.h" 2 | #include 3 | 4 | Benders::Benders(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 5 | { 6 | //ctor 7 | GAP = GAPinstance; 8 | m = GAP->m; 9 | n = GAP->n; 10 | sol = GAP->sol; 11 | solbest = GAP->solbest; 12 | req = GAP->req; 13 | } 14 | 15 | Benders::~Benders() 16 | { 17 | //dtor 18 | } 19 | 20 | /* 21 | BEND HEURISTIC() 22 | 1 identify a master MP(z,y) and an “easy” subproblem SP(x), set t = 0 23 | 2 repeat 24 | 3 solve (heuristically) master problem MPt . Solution (zt , yt ) 25 | 4 if x are requested to be integer 26 | 5 then solve (heuristically) problem SP(x), solution (zH , xt ) 27 | 6 solve problem DP(wt ), solution (zd , wt ), and add to MP the 28 | corresponding cut 29 | 7 if no more cuts can be added 30 | 8 then STOP else set t = t + 1 31 | 9 until (end_condition) 32 | */ 33 | int Benders::bendersHeu(int** c, int maxiter, bool fVerbose) 34 | { int* solIter = new int[n]; 35 | double zMaster; // Bender's bound 36 | double zSubpr; // subproblem cost 37 | 38 | if(GAP->n == NULL) 39 | { cout << "Instance undefined. Exiting" << endl; 40 | return INT_MAX; 41 | } 42 | isVerbose = fVerbose; 43 | 44 | int numRows, numCols, numNZrow, nServKept; 45 | nServKept = m / 3; // keeping 1/3 of capacity constraints 46 | numRows = 1 + nServKept; 47 | numCols = 1 + n*nServKept; // only vars in the capacities kept 48 | numNZrow = 1 + n; // max num of nonzero values in a row 49 | MIPCplex* CPXmaster = new MIPCplex(numRows, numCols, numNZrow); 50 | CPXmaster->GAP = GAP; 51 | 52 | vector xbar(numCols-1); // client assignmed fixed in master problem 53 | vector wbar(nServKept*n + (m - nServKept)); // subproblem duals 54 | 55 | cout << "Benders. Keeping first " << nServKept << " capacity constraints in master" << endl; 56 | 57 | try 58 | { 59 | zSubpr = DBL_MAX; 60 | zMaster = 0; 61 | AllocateMaster(CPXmaster,nServKept, isVerbose); 62 | 63 | cout << "Benders heuristic to be completed" << endl; 64 | goto lend; 65 | 66 | while ((zSubpr-zMaster) > 0.01) 67 | { 68 | AddBendersCut(CPXmaster,wbar,nServKept); 69 | zMaster = SolveMaster(CPXmaster, numRows, nServKept, xbar, wbar, isVerbose); 70 | zSubpr = SolveDLGAP(xbar, wbar, nServKept, isVerbose); 71 | } 72 | } 73 | catch(std::exception const& e) 74 | { cout << "Error: " << e.what() << endl; 75 | goto lend; 76 | } 77 | 78 | cout << "Bender's, bound = " << zMaster << endl; 79 | 80 | lend: 81 | CPXmaster->freeMIP(); 82 | delete(CPXmaster); 83 | return 0; 84 | } 85 | 86 | // Allocates the CPLEX memory structures for the master core 87 | void Benders::AllocateMaster(MIPCplex* CPX, int nServKept, bool isVerbose) 88 | { 89 | int i, j, status, numNZrow, idRow; 90 | 91 | try 92 | { 93 | status = 0; 94 | CPX->env = NULL; 95 | CPX->lp = NULL; 96 | CPX->pi = NULL; 97 | CPX->dj = NULL; 98 | CPX->x = NULL; 99 | CPX->slack = NULL; 100 | 101 | cout << "Allocating CPLEX for master" << endl; 102 | CPX->env = CPXopenCPLEX(&status); 103 | if (CPX->env == NULL) 104 | { 105 | char errmsg[1024]; 106 | cerr << "Could not open CPLEX environment.\n"; 107 | CPXgeterrorstring(CPX->env, status, errmsg); 108 | cerr << errmsg; 109 | goto lend; 110 | } 111 | 112 | // Turn on output to the screen 113 | if (isVerbose) 114 | status = CPXsetintparam(CPX->env, CPX_PARAM_SCRIND, CPX_ON); 115 | else 116 | status = CPXsetintparam(CPX->env, CPX_PARAM_SCRIND, CPX_OFF); 117 | if (status) 118 | { 119 | cerr << "Failure to turn on screen indicator, error " << status << endl; 120 | goto lend; 121 | } 122 | 123 | // Turn on data checking 124 | status = CPXsetintparam(CPX->env, CPX_PARAM_DATACHECK, CPX_ON); 125 | if (status) 126 | { 127 | cerr << "Failure to turn on data checking, error " << status << endl; 128 | goto lend; 129 | } 130 | 131 | // Create the problem. 132 | CPX->lp = CPXcreateprob(CPX->env, &status, "GAPinst"); 133 | if (CPX->lp == NULL) 134 | { 135 | cerr << "Failed to create LP.\n"; 136 | goto lend; 137 | } 138 | 139 | CPXchgobjsen(CPX->env, CPX->lp, CPX_MIN); // Problem is minimization 140 | 141 | // Create the new columns 142 | int ij = 0; 143 | 144 | // z column 145 | CPX->obj[ij] = 1.0; 146 | CPX->lb[ij] = 0; 147 | CPX->ub[ij] = DBL_MAX; 148 | CPX->ctype[ij] = 'C'; // 'B', 'I','C' to indicate binary, general integer, continuous 149 | CPX->lptype[ij] = 'C'; // 'B', 'I','C' to indicate binary, general integer, continuous 150 | CPX->colname[ij] = (char *)malloc(sizeof(char) * (11)); // why not 11? 151 | sprintf(CPX->colname[ij], "%s", "z"); 152 | ij++; 153 | 154 | for (i = 0; in; j++) 156 | { 157 | CPX->obj[ij] = 0.0; 158 | CPX->lb[ij] = 0; 159 | CPX->ub[ij] = 1.0; 160 | CPX->ctype[ij] = 'B'; // 'B', 'I','C' to indicate binary, general integer, continuous 161 | CPX->lptype[ij] = 'C'; // 'B', 'I','C' to indicate binary, general integer, continuous 162 | CPX->colname[ij] = (char *)malloc(sizeof(char) * (11)); // why not 11? 163 | sprintf(CPX->colname[ij], "%s%d", "x", ij); 164 | ij++; 165 | } 166 | 167 | status = CPXnewcols(CPX->env, CPX->lp, CPX->numCols, CPX->obj, CPX->lb, CPX->ub, NULL, CPX->colname); 168 | if (status) goto TERMINATE; 169 | 170 | idRow = 0; 171 | 172 | // z contraint 173 | numNZrow = 0; // number of nonzero element in the row to add 174 | CPX->rmatbeg[0] = 0; 175 | CPX->sense[0] = 'G'; 176 | CPX->rhs[0] = 0; 177 | CPX->rowname[idRow] = (char *)malloc(sizeof(char) * (11)); // why not 11? 178 | sprintf(CPX->rowname[0], "%s%d", "z", idRow); 179 | CPX->rmatind[numNZrow] = 0; 180 | CPX->rmatval[numNZrow] = 1; 181 | numNZrow++; 182 | for (i = 0; in; j++) 184 | { 185 | CPX->rmatind[numNZrow] = 1 + j + GAP->n*i; 186 | CPX->rmatval[numNZrow] = -GAP->c[i][j]; 187 | numNZrow++; 188 | } 189 | CPX->rmatbeg[1] = numNZrow; 190 | status = CPXaddrows(CPX->env, CPX->lp, 0, 1, numNZrow, CPX->rhs, CPX->sense, CPX->rmatbeg, CPX->rmatind, CPX->rmatval, NULL, CPX->rowname); 191 | if (status) 192 | goto TERMINATE; 193 | idRow++; 194 | 195 | // Capacity constraints 196 | for (i = 0; irmatbeg[0] = 0; 200 | CPX->sense[0] = 'L'; 201 | CPX->rhs[0] = GAP->cap[i]; 202 | CPX->rowname[idRow] = (char *)malloc(sizeof(char) * (11)); // why not 11? 203 | sprintf(CPX->rowname[0], "%s%d", "c", idRow); 204 | for (j = 0; jn; j++) 205 | { 206 | CPX->rmatind[numNZrow] = 1 + j + GAP->n*i; 207 | CPX->rmatval[numNZrow] = GAP->req[i][j]; 208 | numNZrow++; 209 | } 210 | CPX->rmatbeg[1] = numNZrow; 211 | status = CPXaddrows(CPX->env, CPX->lp, 0, 1, numNZrow, CPX->rhs, CPX->sense, CPX->rmatbeg, CPX->rmatind, CPX->rmatval, NULL, CPX->rowname); 212 | if (status) 213 | goto TERMINATE; 214 | idRow++; 215 | } 216 | } 217 | catch (std::exception const& e) 218 | { 219 | cout << "[SolveMaster] Error: " << e.what() << endl; 220 | goto lend; 221 | } 222 | 223 | TERMINATE: 224 | if (status) 225 | cout << "[AllocateMaster] --------------- Error in constraint definition" << endl; 226 | 227 | lend: 228 | return; 229 | } 230 | 231 | // Add a Benedr's cut 232 | void Benders::AddBendersCut(MIPCplex* CPX, vector wbar, int nServKept) 233 | { 234 | int i,j,ij, numNZrow, status; 235 | int numVarDL = nServKept*n + (m - nServKept); 236 | 237 | // z contraint 238 | numNZrow = 0; // number of nonzero element in the row to add 239 | CPX->rmatbeg[0] = 0; 240 | CPX->sense[0] = 'G'; 241 | CPX->rhs[0] = 0; 242 | for(i=0;im-nServKept;i++) 243 | CPX->rhs[0] += wbar[nServKept*n+i]*GAP->cap[nServKept+i]; 244 | CPX->rowname[0] = (char *)malloc(sizeof(char) * (11)); // why not 11? 245 | sprintf(CPX->rowname[0], "%s%d", "B", CPXgetnumrows(CPX->env, CPX->lp)); 246 | CPX->rmatind[numNZrow] = 0; 247 | CPX->rmatval[numNZrow] = 1; 248 | numNZrow++; 249 | ij=0; 250 | for (i = 0; in; j++) 252 | { 253 | CPX->rmatind[numNZrow] = 1 + j + GAP->n*i; 254 | CPX->rmatval[numNZrow] = -wbar[ij]; 255 | CPX->rhs[0] += wbar[ij]; 256 | numNZrow++; 257 | ij++; 258 | } 259 | CPX->rmatbeg[1] = numNZrow; 260 | status = CPXaddrows(CPX->env, CPX->lp, 0, 1, numNZrow, CPX->rhs, CPX->sense, CPX->rmatbeg, CPX->rmatind, CPX->rmatval, NULL, CPX->rowname); 261 | if (status) 262 | cout << "[AddBendersCut] Error."; 263 | } 264 | 265 | double Benders::SolveMaster(MIPCplex* CPX, int numRows, int nServKept, vector & x1, vector wbar, bool isVerbose) 266 | { int i, j, status; 267 | double zMaster=DBL_MIN; 268 | 269 | try 270 | { 271 | status = 0; 272 | 273 | // Write a copy of the problem to a file. 274 | if (isVerbose) 275 | { 276 | status = CPXwriteprob(CPX->env, CPX->lp, "GAPmaster.lp", NULL); 277 | if (status) 278 | { cerr << "[Error "<solveMIP(true, false); // integer solution 284 | if (!status) 285 | { 286 | zMaster = CPX->objval; 287 | for (i = 0; i < nServKept; ++i) 288 | for (j = 0; j < n; ++j) 289 | x1[i*n + j] = (int) CPX->x[i*n + j +1]; // +1 remoeves the z 290 | } 291 | } 292 | catch (std::exception const& e) 293 | { 294 | cout << "[SolveMaster] Error: " << e.what() << endl; 295 | goto lend; 296 | } 297 | 298 | lend: 299 | return zMaster; 300 | } 301 | 302 | // Duale del ril. lineare 303 | double Benders::SolveDLGAP(vector xbar, vector & wbar, int nServKept, bool isVerbose) 304 | { 305 | int j, numVarDL, status; 306 | double zDL = -1; 307 | 308 | int numRows, numCols, numNZrow; 309 | numRows = n*(m-nServKept); // num of constraints 310 | numCols = numVarDL = nServKept*n + (m - nServKept); // num of variables 311 | numNZrow = 2; // max num of nonzero values in a row 312 | 313 | try 314 | { 315 | MIPCplex* CPX = new MIPCplex(numRows, numCols, numNZrow); 316 | CPX->GAP = GAP; 317 | CPX->allocateDual(numRows, numCols, xbar, isVerbose); 318 | 319 | status = CPX->solveMIP(false, false); // linear 320 | 321 | cout << "\nLP Solution status = " << status << endl; 322 | if(!status) 323 | { zDL = CPX->objval; 324 | cout << "LP Solution value = " << CPX->objval << endl; 325 | for (j = 0; j < numVarDL; ++j) 326 | wbar[j] = CPX->x[j]; 327 | 328 | if (n*m < 101) // print LP if instance is small 329 | { cout << " - Solution: " << endl; 330 | for (j = 0; j < numVarDL; ++j) 331 | cout << CPX->x[j] << "\t"; 332 | cout << endl; 333 | } 334 | } 335 | 336 | CPX->freeMIP(); 337 | delete(CPX); 338 | } 339 | catch (std::exception const& e) 340 | { 341 | cout << "[SolveDLGAP]: " << e.what() << endl; 342 | } 343 | 344 | return(zDL); 345 | } -------------------------------------------------------------------------------- /Benders.h: -------------------------------------------------------------------------------- 1 | #ifndef BENDERS_H 2 | #define BENDERS_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include // std::find 9 | #include "MIPCplex.h" 10 | 11 | class Benders 12 | { 13 | public: 14 | GeneralizedAssignemnt* GAP; 15 | 16 | Benders(GeneralizedAssignemnt*, int&); 17 | ~Benders(); 18 | int bendersHeu(int** c, int maxiter, bool fVerbose); 19 | 20 | private: 21 | // local mirrors 22 | int m,n; 23 | int *sol,*solbest; 24 | int** req; 25 | int & zub,zlb; 26 | bool isVerbose; 27 | 28 | void Benders::AllocateMaster(MIPCplex* CPX, int nServKept, bool isVerbose); 29 | double Benders::SolveMaster(MIPCplex* CPX, int, int, vector &, vector, bool isVerbose); 30 | double Benders::SolveDLGAP(vector, vector &,int,bool); 31 | void AddBendersCut(MIPCplex* CPX, vector wbar, int nServKept); 32 | }; 33 | 34 | #endif // BENDERS_H 35 | -------------------------------------------------------------------------------- /ConstructHeu.cpp: -------------------------------------------------------------------------------- 1 | #include "ConstructHeu.h" 2 | 3 | ConstructHeu::ConstructHeu(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | ConstructHeu::~ConstructHeu() 15 | { 16 | //dtor 17 | } 18 | 19 | // constructive: each at its least disliked facility 20 | int ConstructHeu::simpleConstruct() 21 | { int i,ii,j,jj,m,n; 22 | 23 | m = GAP->m; 24 | n = GAP->n; 25 | vector cost(m),capleft(m),indReq(m); 26 | vector regrets(n),indCost(n); 27 | auto compCost = [&cost](int a, int b){ return cost[a] < cost[b]; }; // ASC order 28 | auto compRegr = [®rets](int a, int b){ return regrets[a] > regrets[b]; }; // DESC order 29 | 30 | if(GAP->n == NULL) 31 | { cout << "Instance undefined. Exiting" << endl; 32 | return INT_MAX; 33 | } 34 | 35 | zub = INT_MAX; 36 | 37 | for(i=0;icap[i]; 38 | computeRegrets(GAP->c,n,m,regrets); 39 | 40 | for(j=0;javersion(i,j); 48 | indReq[i] = i; 49 | } 50 | 51 | std::sort(indReq.begin(), indReq.end(), compCost); // prefer low cost 52 | 53 | ii=0; 54 | while(ii=GAP->req[i][j]) 57 | { GAP->sol[j]=i; 58 | GAP->solbest[j]=i; 59 | capleft[i] -= GAP->req[i][j]; 60 | zub += GAP->c[i][j]; 61 | break; 62 | } 63 | ii++; 64 | } 65 | if(ii==m) 66 | { cout << "[SimpleConstruct] Error. ii="+ii << endl; 67 | zub = INT_MAX; 68 | break; 69 | } 70 | } 71 | if(abs(GAP->checkSol(GAP->sol)-zub) > GAP->EPS) 72 | { cout << "[simpleContruct]: Error" << endl; 73 | zub = INT_MAX; 74 | } 75 | else 76 | { cout << "Construction terminated. Zub = " << zub << endl; 77 | printIntArray(sol,n); 78 | } 79 | for(int k=0;k indCost, bool isVerbose) 85 | { int i,ii,j,jj,m,n,z; 86 | 87 | m = GAP->m; 88 | n = GAP->n; 89 | vector cost(m),capleft(m),indReq(m); 90 | vector regrets(n); 91 | auto compCost = [&cost](int a, int b){ return cost[a] < cost[b]; }; // ASC order 92 | auto compRegr = [®rets](int a, int b){ return regrets[a] > regrets[b]; }; // DESC order 93 | 94 | if(GAP->n == NULL) 95 | { if(isVerbose) cout << "Instance undefined. Exiting" << endl; 96 | return INT_MAX; 97 | } 98 | 99 | z = INT_MAX; 100 | for(i=0;icap[i]; 101 | 102 | z = 0; 103 | for(jj=0;jjaversion(i,j); 107 | indReq[i] = i; 108 | } 109 | 110 | std::sort(indReq.begin(), indReq.end(), compCost); 111 | 112 | ii=0; 113 | while(ii=GAP->req[i][j]) 116 | { GAP->sol[j]=i; 117 | capleft[i] -= GAP->req[i][j]; 118 | z += GAP->c[i][j]; 119 | break; 120 | } 121 | ii++; 122 | } 123 | 124 | if(ii==m) 125 | { if(isVerbose) cout << "[Construct] Error. ii="+ii << endl; 126 | z = INT_MAX; 127 | break; 128 | } 129 | } 130 | 131 | if(abs(GAP->checkSol(GAP->sol)-z) > GAP->EPS) 132 | { if(isVerbose) cout << "[Contruct]: Error" << endl; 133 | z = INT_MAX; 134 | } 135 | else 136 | { if(isVerbose) cout << "Construction terminated. z = " << z << endl; 137 | if(isVerbose) printIntArray(sol,n); 138 | 139 | if(z indCost, bool isVerbose); 14 | 15 | private: 16 | //void computeRegrets(vector &); 17 | 18 | // local mirrors 19 | int m,n; 20 | int *sol,*solbest; 21 | int** req; 22 | int & zub,zlb; 23 | }; 24 | 25 | #endif // CONSTRUCTHEU_H 26 | -------------------------------------------------------------------------------- /Controller.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTROLLER_H 2 | #define CONTROLLER_H 3 | #include "GAP.h" 4 | #include "Persistence.h" 5 | #include "ConstructHeu.h" 6 | #include "LocalSearch.h" 7 | #include "MTHG.h" 8 | #include "LowerBound.h" 9 | #include "SimAnnealing.h" 10 | #include "TabuSearch.h" 11 | #include "GeneticAlgorithm.h" 12 | #include "ACO.h" 13 | #include "SS.h" 14 | #include "Ejection.h" 15 | #include "MetaLocalSearch.h" 16 | #include "Lagrangian.h" 17 | #include "Rins.h" 18 | #include "BeamSearch.h" 19 | #include "ForwardBackward.h" 20 | #include "Corridor.h" 21 | #include "LocBranching.h" 22 | #include "Benders.h" 23 | #include "Kernel.h" 24 | #include "VLSN.h" 25 | 26 | class Controller 27 | { 28 | public: 29 | Persistence* P; // read config and instance 30 | GeneralizedAssignemnt* GAP; // global data structures 31 | ConstructHeu* CH; // simple constructive 32 | MTHG* MT; // Martello and Toth heuristic 33 | LowerBound* LB; // aka cplex 34 | LocalSearch* LS; // local search (10, 11, 21) 35 | SimAnnealing* SA; // Simulated Annealing (bare) 36 | TabuSearch* TS; // Tabu search 37 | GenAlgo* GA; // Genetic algorithm 38 | ACO* ANTS; // ant colony optimization 39 | ScatterSearch* SS; // Scatter search 40 | Ejection* EC; // Ejection chain 41 | MetaLocalSearch* MLS; // ILS, VND, VNS 42 | Lagrangian* LAGR; // lagrangian, assignment and capacities 43 | Rins* RINS; // Rins, would you guess? 44 | BeamSearch* BS; // Beam search 45 | FandB* FB; // Forward and backward 46 | Corridor* CORR; // Corridor 47 | LocBranching* LBR; // Local Branching 48 | Benders* BEND; // Benders 49 | Kernel* KER; // Kernel 50 | VeryLarge* VLSN; // Very large-scale neighborhood search 51 | 52 | Controller(); 53 | ~Controller(); 54 | void readJSONdata(string filename); // reads data from json file 55 | double simpleConstruct(); 56 | void computeBounds(); 57 | double exactCplex(); 58 | int run_mthg(); 59 | int opt10(); 60 | int run_simAnn(); 61 | int run_tabuSearch(); 62 | int run_iteratedLS(); 63 | int run_GRASP(); 64 | int run_VNS(); 65 | int run_genAlgo(); 66 | int run_ACO(); 67 | int run_SS(); 68 | int run_ejection(); 69 | int run_lagrAss(); 70 | int run_lagrCap(); 71 | int run_rins(); 72 | int run_beam(); 73 | int run_FandB(); 74 | int run_Corridor(); 75 | int run_localBranching(); 76 | int run_benders(); 77 | int run_kernel(); 78 | int run_VLSN(); 79 | 80 | private: 81 | }; 82 | 83 | #endif // CONTROLLER_H 84 | -------------------------------------------------------------------------------- /Corridor.cpp: -------------------------------------------------------------------------------- 1 | #include "Corridor.h" 2 | 3 | Corridor::Corridor(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | Corridor::~Corridor() 15 | { 16 | //dtor 17 | } 18 | 19 | int Corridor::solveByCorridor(int** c, int delta, int maxiter, bool fVerbose) 20 | { int i,j,iter,status; 21 | int zubIter; 22 | int* solIter = new int[n]; 23 | 24 | if(GAP->n == NULL) 25 | { cout << "Instance undefined. Exiting" << endl; 26 | return INT_MAX; 27 | } 28 | isVerbose = fVerbose; 29 | 30 | int numRows,numCols,numNZrow; 31 | numRows = n+m; // num of constraints 32 | numCols = n*m; // num of variables 33 | numNZrow= n*m; // max num of nonzero values in a row 34 | MIPCplex* CPX = new MIPCplex(numRows,numCols,numNZrow); 35 | CPX->GAP = GAP; 36 | CPX->allocateMIP(isVerbose); 37 | zubIter = zub; 38 | for(j=0;jx[i*n+j] << "\t"; 57 | cout << endl; 58 | } 59 | } 60 | // reads the solution 61 | zubIter = 0; 62 | for(j=0;jx[i*n+j] > 0.5) 65 | { solIter[j] = i; 66 | break; 67 | } 68 | zubIter += c[solIter[j]][j]; 69 | } 70 | 71 | if(abs(zubIter - GAP->checkSol(solIter)) > GAP->EPS) 72 | cout << "[solveByCorridor] No feasible solution at this iteration" << endl; 73 | else 74 | { cout << "[Corridor] iter "<< iter <<" zubIter "<< zubIter << endl; 75 | cout << "Solution: "; for(j=0;jfreeMIP(); 93 | delete(CPX); 94 | delete(solIter); 95 | return zub; 96 | } 97 | 98 | // this frees the variables in the corridor 99 | void Corridor::updateModelWithCorridor(MIPCplex* CPX, int* solIter, int delta) 100 | { int i,j,isol,rand,status; 101 | bool isInCorridor; 102 | vector lstClient; 103 | vector lstCorridor; 104 | 105 | for(i=0;ilb[i*n+j] == 0.0) // lb OK, only ub could be wrong 134 | { CPX->ub[i*n+j] = 1.0; 135 | bd[i*n+j] = 1.0; 136 | lu[i*n+j] = 'U'; // bd[j] is an upper bound 137 | } 138 | else // lb wrong, ub should be OK 139 | { CPX->lb[i*n+j] = 0.0; 140 | bd[i*n+j] = 0.0; 141 | lu[i*n+j] = 'L'; // bd[j] is an upper bound 142 | } 143 | } 144 | else // not in corridor 145 | { isol = solIter[j]; 146 | if(i==isol) 147 | { CPX->lb[i*n+j] = 1.0; // fixing in the solution 148 | bd[i*n+j] = 1.0; 149 | } 150 | else 151 | { CPX->lb[i*n+j] = 0.0; // forbidding in the solution 152 | bd[i*n+j] = 0.0; 153 | } 154 | lu[i*n+j] = 'B'; // bd[j] is the lower and upper bound 155 | } 156 | indices[i*n+j] = i*n+j; 157 | } 158 | } 159 | cout << endl; 160 | 161 | status = CPXchgbds(CPX->env, CPX->lp, cnt, indices, lu, bd); 162 | free(indices); 163 | free(lu); 164 | free(bd); 165 | 166 | return; 167 | } 168 | 169 | 170 | -------------------------------------------------------------------------------- /Corridor.h: -------------------------------------------------------------------------------- 1 | #ifndef CORRIDOR_H 2 | #define CORRIDOR_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include // std::find 9 | #include "MIPCplex.h" 10 | 11 | class Corridor 12 | { 13 | public: 14 | GeneralizedAssignemnt* GAP; 15 | 16 | Corridor(GeneralizedAssignemnt*, int&); 17 | ~Corridor(); 18 | int solveByCorridor(int** c, int delta, int maxiter, bool fVerbose); 19 | 20 | private: 21 | // local mirrors 22 | int m,n; 23 | int *sol,*solbest; 24 | int** req; 25 | int & zub,zlb; 26 | bool isVerbose; 27 | 28 | void updateModelWithCorridor(MIPCplex* CPX, int* solIter, int delta); 29 | }; 30 | 31 | #endif // CORRIDOR_H 32 | -------------------------------------------------------------------------------- /Ejection.cpp: -------------------------------------------------------------------------------- 1 | #include "Ejection.h" 2 | 3 | Ejection::Ejection(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | Ejection::~Ejection() 15 | { 16 | //dtor 17 | } 18 | 19 | int Ejection::ejectionChain(int** c, int maxiter) 20 | { int z=0; 21 | double* x = new double[n*m]; // an LP solution 22 | int* sol; 23 | 24 | sol = generateOneSol(&z); 25 | 26 | cout << "Here would be feasibility pump. Commented out" << endl; 27 | if(z<0) // keeping FP in 28 | { double zlp = DBL_MAX; 29 | sol = feasibilityPump(1000,x,zlp); 30 | } 31 | 32 | cout << "[EC] z = " << z << endl; 33 | 34 | delete x; 35 | return z; 36 | } 37 | 38 | int* Ejection::generateOneSol(int* zval) 39 | { int i,j,k,c1,c2,temp,numRetry=0; 40 | int* newsol = new int[n]; 41 | int z = 0; // soluton cost 42 | vector cost(m),capleft(m),indReq(m),ind(n); 43 | auto compCost = [&cost](int a, int b){ return cost[a] < cost[b]; }; // ASC order, predecate for sort 44 | 45 | for(i=0;icap[i]; // residual capacities 46 | for(j=0;javersion(i,j); // generalized cost for ordering 64 | indReq[i] = i; // server index for requests ordering 65 | } 66 | 67 | std::sort(indReq.begin(), indReq.end(), compCost); // sort by increasing gen cost 68 | k = std::rand() % 3; // random among candate set of best 3 69 | newsol[j] = indReq[k]; 70 | z += GAP->c[newsol[j]][j]; 71 | } 72 | 73 | if(z >= INT_MAX || abs(GAP->checkSol(newsol)-z) > GAP->EPS) 74 | { //GAP->fixSol(newsol,&z); 75 | GAP->fixSolViaKnap(newsol, &z); 76 | if(z >= INT_MAX || abs(GAP->checkSol(newsol)-z) > GAP->EPS) 77 | { numRetry++; 78 | if(numRetry < 5) 79 | goto l0; 80 | else if (numRetry < 10) 81 | { GAP->fixSolViaKnap(newsol,&z); 82 | if(z >= INT_MAX || abs(GAP->checkSol(newsol)-z) > GAP->EPS) 83 | goto l0; 84 | } 85 | else 86 | { 87 | cout << "[generateOneSol]: infeasible" << endl; 88 | newsol = nullptr; 89 | } 90 | } 91 | } 92 | cout << "[generateOneSol]: z = " << (*zval = z) << endl; 93 | 94 | return newsol; 95 | } 96 | 97 | int* Ejection::feasibilityPump(int maxIter, double* x, double zlp) 98 | { int i,j,iter,status; 99 | MIPCplex* CPX; 100 | vector sigma(n*m); 101 | vector indSigma(n*m); 102 | int* indices = new int[n*m]; // for cost coef update 103 | double* ofvalues = new double[n*m]; // for cost coef update 104 | double* xRound = new double[n*m]; 105 | double z = DBL_MAX, delta = DBL_MAX; 106 | bool isDifferent; 107 | auto compSigma = [&sigma](int a, int b) { return sigma[a] > sigma[b]; }; // DESC order 108 | 109 | int numRows, numCols, numNZrow; 110 | numRows = n+m; // num of constraints 111 | numCols = n*m; // num of variables 112 | numNZrow = n*m; // max num of nonzero values in a row 113 | try 114 | { 115 | cout << "Entering feasibility pump" << endl; 116 | CPX = new MIPCplex(numRows, numCols, numNZrow); 117 | CPX->GAP = GAP; 118 | CPX->allocateMIP(false); 119 | int cur_numcols = CPXgetnumcols(CPX->env, CPX->lp); 120 | int cur_numrows = CPXgetnumrows(CPX->env, CPX->lp); 121 | 122 | // set initial LP solution 123 | int* cstat = (int *)malloc(cur_numcols * sizeof(int)); 124 | int* rstat = (int *)malloc(cur_numrows * sizeof(int)); 125 | status = setInitialBasis(CPX,x,cstat,rstat,zlp); 126 | 127 | status = CPXcopybase(CPX->env, CPX->lp, cstat, rstat); 128 | if (status) 129 | { fprintf(stderr, "Failed to copy the basis.\n"); 130 | goto lend; 131 | } 132 | 133 | // here we get the starting LP and rounded solutions 134 | status = CPX->solveMIP(false, false); 135 | if (status == 0) 136 | { 137 | double lb = CPX->objval; // useless, but nice to know 138 | cout << "Linear bound: " << lb << endl; 139 | for (i = 0; i < m; ++i) 140 | for (j = 0; j < n; ++j) 141 | { x[i*n + j] = CPX->x[i*n + j]; 142 | xRound[i*n + j] = round(x[i*n + j]); 143 | } 144 | } 145 | cout << "Initial LP solution: "; printDblArray(x,n*m); 146 | 147 | for (iter = 0; (iter GAP->EPS); iter++) 148 | { 149 | //printDblArray(x, n*m); 150 | //printDblArray(xRound, n*m); 151 | for (i = 0; i < m; ++i) // redefinition of of cost coefficients 152 | for (j = 0; j < n; ++j) 153 | { ofvalues[i*n +j] = (xRound[i*n+j] < GAP->EPS ? x[i*n+j] : (1-x[i*n+j]) ); 154 | indices[i*n + j] = i*n + j; 155 | } 156 | status = CPXchgobj(CPX->env, CPX->lp, n*m, indices, ofvalues); 157 | int statusMIP = CPX->solveMIP(false, false); 158 | double cst = 0; 159 | if (statusMIP == 0) 160 | { cst = CPX->objval; // could be useless, but nice to know 161 | for (i = 0; i < m; ++i) 162 | for (j = 0; j < n; ++j) 163 | x[i*n + j] = CPX->x[i*n + j]; 164 | } 165 | 166 | delta = 0; 167 | isDifferent = false; 168 | for (i = 0; i < m; ++i) 169 | for (j = 0; j < n; ++j) 170 | { sigma[i*n + j] = abs(x[i*n + j] - xRound[i*n + j]); // could be also computed as above 171 | delta += sigma[i*n + j]; 172 | if(round(x[i*n + j]) != xRound[i*n + j]) 173 | isDifferent = true; 174 | } 175 | cout << "FP iter: " << iter << " lp " << cst << " delta: " << delta << endl; 176 | 177 | if(delta>0) 178 | { if(isDifferent && ((iter+1)%n > 0)) // heuristic perturbations added every tot iterations 179 | for (i = 0; i < m; ++i) 180 | for (j = 0; j < n; ++j) 181 | xRound[i*n + j] = round(x[i*n + j]); 182 | else 183 | { 184 | for (j = 0; jEPS) 208 | { cout << "Delta= " << delta << endl; 209 | z = 0; 210 | for (i = 0; i < m; ++i) 211 | for (j = 0; j < n; ++j) 212 | if(xRound[i*n + j] == 1) 213 | { sol[j] = i; 214 | z += GAP->c[i][j]; 215 | } 216 | cout << "Final LP solution: "; printDblArray(x, n*m); 217 | cout << "Final rounded solution: "; printDblArray(x, n*m); 218 | 219 | zlp = z; 220 | if (abs(GAP->checkSol(sol) - z) > GAP->EPS) 221 | { 222 | cout << "[FP]: Error" << endl; 223 | zub = INT_MAX; 224 | } 225 | else 226 | cout << "[FP] Construction terminated. z = " << z << endl; 227 | } 228 | 229 | lend: 230 | CPX->freeMIP(); 231 | delete(CPX); 232 | delete(xRound); 233 | delete(ofvalues); 234 | delete(indices); 235 | return sol; 236 | } 237 | 238 | // starting LP solution for FP. There must be a better way to impement this but this is how far my cplex mastering goes 239 | int Ejection::setInitialBasis(MIPCplex* CPX, double* x, int* cstat, int* rstat, double z) 240 | { int status; 241 | 242 | if(z==DBL_MAX) 243 | { 244 | status = CPXlpopt(CPX->env, CPX->lp); 245 | if (status) 246 | { fprintf(stderr, "Failed to optimize LP.\n"); 247 | goto lend; 248 | } 249 | 250 | int solnstat = CPXgetstat(CPX->env, CPX->lp); 251 | 252 | if (solnstat == CPX_STAT_UNBOUNDED) 253 | { printf("Model is unbounded\n"); 254 | goto lend; 255 | } 256 | else if (solnstat == CPX_STAT_INFEASIBLE) 257 | { printf("Model is infeasible\n"); 258 | goto lend; 259 | } 260 | else if (solnstat == CPX_STAT_INForUNBD) 261 | { printf("Model is infeasible or unbounded\n"); 262 | goto lend; 263 | } 264 | status = CPXgetbase(CPX->env, CPX->lp, cstat, rstat); 265 | } 266 | 267 | lend: 268 | return status; 269 | } -------------------------------------------------------------------------------- /Ejection.h: -------------------------------------------------------------------------------- 1 | #ifndef EJECTION_H 2 | #define EJECTION_H 3 | #include "GAP.h" 4 | #include "Rins.h" 5 | #include "MIPCplex.h" 6 | 7 | class Ejection 8 | { 9 | public: 10 | GeneralizedAssignemnt* GAP; 11 | 12 | Ejection(GeneralizedAssignemnt*, int&); 13 | ~Ejection(); 14 | int ejectionChain(int**, int); 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | 23 | // private functions 24 | int* generateOneSol(int*); 25 | int* feasibilityPump(int,double*,double); 26 | int setInitialBasis(MIPCplex*,double* x, int* cstat, int* rstat, double); 27 | }; 28 | 29 | #endif // EJECTION_H 30 | -------------------------------------------------------------------------------- /ForwardBackward.h: -------------------------------------------------------------------------------- 1 | #ifndef FANDB_H 2 | #define FANDB_H 3 | #include "GAP.h" 4 | #include 5 | #include // std::copy 6 | 7 | class FandB 8 | { 9 | public: 10 | GeneralizedAssignemnt* GAP; 11 | 12 | FandB(GeneralizedAssignemnt*, int&); 13 | ~FandB(); 14 | int forwardBackward(int** c, int delta, int maxNodes, bool fVerbose); 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | bool isVerbose; 23 | 24 | // the state of each partial solution 25 | struct node 26 | { int z; // cost of the partial soluton 27 | int client; // the assigned client 28 | int server; // who the client is assigned to 29 | int dad; // which sol was expanded into this 30 | vector capused; // array of used capacities 31 | }; 32 | 33 | vector stack; // stack all nodes expanded during search 34 | vector> fTree; // forward tree, one list for each level / customer 35 | vector> bTree; // backward tree, one list for each level / customer 36 | vector> fList; // the list of still unexpanded nodes at each level of the forward tree 37 | vector> bList; // the list of still unexpanded nodes at each level of the backward tree 38 | vector fTopCost; // max cost of expanded node at each level of the forward tree 39 | vector bTopCost; // max cost of expanded node at each level of the backward tree 40 | 41 | int indLastNode; // aka stack.size(). just it 42 | int numFathomed; // num fahtomed nodes 43 | 44 | int sweepForward(ofstream&, int iter, int** c, int delta, int maxNodes, int openNodes, vector indCost); 45 | int sweepBackward(ofstream&, int iter, int** c, int delta, int maxNodes, int openNodes, vector indCost); 46 | int expandNode(ofstream&, int iter, int** c, int j, int jlev, int currNode, vector indCost, bool isForward); // generates feasible offspring of a node 47 | int insertInOrder(list & lst, int ind); // inserts a stack index in a list, ordered on a key 48 | int readSolutionF(ofstream&, int currNode, vector indCost); // reads the solutions from a last node of the forward tree 49 | int readSolutionB(ofstream&, int currNode, vector indCost); // reads the solutions from a last node of the backward tree 50 | int readSolutionFB(ofstream&, int jLevF, int fNode, int bNode, vector indCost); // reads the solution as a mix of forw and a backw partials 51 | int findNextNodeF(int jlev, int newNodes, int openNodes); // finds the next node to expand forward 52 | int findNextNodeB(int jlev, int newNodes, int openNodes); // finds the next node to expand backward 53 | int checkMatch(ofstream&, int iter, int jlev, int indLastNode, bool isForward, vector indCost);// checks for matching partial solutions 54 | }; 55 | 56 | #endif // FANDB_H 57 | -------------------------------------------------------------------------------- /GAP.h: -------------------------------------------------------------------------------- 1 | #ifndef GAP_H 2 | #define GAP_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include /* srand, rand */ 12 | #include /* time */ 13 | #include /* assert */ 14 | #include /* std::sort */ 15 | 16 | using namespace std; 17 | 18 | class Config 19 | { 20 | public: 21 | class SimAnn 22 | { public: 23 | double maxT; 24 | double k; 25 | double alpha; 26 | int iterAnneal; 27 | double coefAnneal; 28 | int maxiter; 29 | int fGoMath; // flag: use matheuristics 30 | friend class Config; 31 | }; 32 | 33 | class Tabu 34 | { public: 35 | int Ttenure; 36 | int maxiter; 37 | int fGoMath; // flag: use matheuristics 38 | }; 39 | 40 | class ILSconf 41 | { public: 42 | int maxiter; 43 | double alpha; 44 | }; 45 | 46 | class GRASPconf 47 | { public: 48 | int maxiter; 49 | int candNum; 50 | }; 51 | 52 | class VNSconf 53 | { public: 54 | int maxiter; 55 | int fGoMath; // flag: use matheuristics 56 | }; 57 | 58 | class GeneticConf 59 | { public: 60 | int maxiter; 61 | int numpop; // num individuals in population 62 | double pc; // crossover probability 63 | }; 64 | 65 | class ACOconf 66 | { public: 67 | int maxiter; 68 | int numpop; // num individuals in population 69 | double alpha; // attractiveness vs trail 70 | }; 71 | 72 | class SSconf 73 | { public: 74 | int maxiter; 75 | int numpop; // num individuals in population 76 | double alpha; // placeholder 77 | }; 78 | 79 | class EjectionConf 80 | { public: 81 | int maxiter; 82 | }; 83 | 84 | class LagrAss 85 | { 86 | public: 87 | double alpha; 88 | double alphastep; 89 | double minalpha; 90 | int maxiter; 91 | int innerIter; 92 | }; 93 | 94 | class RinsConf 95 | { public: 96 | int maxnodes; 97 | }; 98 | 99 | class Beam 100 | { public: 101 | int delta; 102 | int maxnodes; 103 | }; 104 | 105 | class FBconf 106 | { public: 107 | int delta; 108 | int maxnodes; 109 | }; 110 | 111 | class LagrCap 112 | { 113 | public: 114 | double alpha; 115 | double alphastep; 116 | double minalpha; 117 | int maxiter; 118 | int innerIter; 119 | }; 120 | 121 | class CorridorConf 122 | { public: 123 | int delta; 124 | int maxiter; 125 | }; 126 | 127 | class LocBranching 128 | { public: 129 | int k; 130 | int maxiter; 131 | }; 132 | 133 | class BendersConf 134 | { public: 135 | int maxiter; 136 | }; 137 | 138 | class VLSNConf 139 | { public: 140 | int maxiter; 141 | int k; 142 | }; 143 | 144 | // -------------------- reminder: initialize these in the Config constructor! 145 | SimAnn* SA; 146 | Tabu* TS; 147 | GeneticConf* GA; 148 | EjectionConf* EC; 149 | ILSconf* IterLS; 150 | GRASPconf* GRASP; 151 | VNSconf* VNS; 152 | ACOconf* ACO; 153 | SSconf* SS; 154 | LagrAss* lagrAss; 155 | LagrCap* lagrCap; 156 | LocBranching* locBranching; 157 | RinsConf* rinsConf; 158 | Beam* beam; 159 | FBconf* fbConf; 160 | CorridorConf* corridorConf; 161 | BendersConf* bendersConf; 162 | VLSNConf* verylargeConf; 163 | string datafile; 164 | int isVerbose; 165 | int aversionf; 166 | 167 | Config(); 168 | }; 169 | 170 | class GeneralizedAssignemnt 171 | { 172 | public: 173 | GeneralizedAssignemnt(); 174 | ~GeneralizedAssignemnt(); 175 | string name; // instance name 176 | int n; // number of clients 177 | int m; // number of servers 178 | int nDays; // planning horizon (if scheduling) 179 | int** c; // assignment costs 180 | int** req; // client requests 181 | int* cap; // server capacities 182 | 183 | Config* conf; 184 | 185 | int *sol,*solbest; // for each client, its server 186 | int zub,zlb; 187 | 188 | double EPS; 189 | 190 | int checkSol(int* sol); // feasibility check 191 | int checkSol(vector sol); // feasibility check 192 | int fixSol(int* infeasSol, int* zsol); // recovers feasibility in case of partial or overassigned solution 193 | int fixSolViaKnap(int* infeasSol, int* zsol); // recovers feasibility via knapsacks on residual capacities 194 | int aversion(int i,int j); 195 | void storeBest(int* sol, double z); // stores best so far solution 196 | }; 197 | 198 | // free 199 | void computeRegrets(int**, int, int, vector & ); 200 | double KDynRecur(int n, int Kcap, int* Q, double* val, int* Ksol); 201 | void KdecodeSol(int i, int Kcap, int* Q, double* val, int n, double** f, int* sol); 202 | void printIntArray(int* a, int n); 203 | void fprintIntArray(ofstream&, int* a, int n); 204 | void printDblArray(double* a, int n); 205 | 206 | #endif // GAP_H 207 | -------------------------------------------------------------------------------- /GAPVS/GAP.lp: -------------------------------------------------------------------------------- 1 | \ENCODING=ISO-8859-1 2 | \Problem name: GAPinst 3 | 4 | Minimize 5 | obj1: 10 x0 + 11 x1 + 12 x2 + 13 x3 + 14 x4 + 15 x5 + 16 x6 + 17 x7 + 22 x8 6 | + 24 x9 + 26 x10 + 28 x11 + 30 x12 + 32 x13 + 34 x14 + 36 x15 + 60 x16 7 | + 64 x17 + 68 x18 + 72 x19 + 76 x20 + 80 x21 + 84 x22 + 88 x23 8 | Subject To 9 | c0: x0 + x8 + x16 = 1 10 | c1: x1 + x9 + x17 = 1 11 | c2: x2 + x10 + x18 = 1 12 | c3: x3 + x11 + x19 = 1 13 | c4: x4 + x12 + x20 = 1 14 | c5: x5 + x13 + x21 = 1 15 | c6: x6 + x14 + x22 = 1 16 | c7: x7 + x15 + x23 = 1 17 | c8: 48 x0 + 47 x1 + 46 x2 + 45 x3 + 44 x4 + 43 x5 + 42 x6 + 41 x7 <= 160 18 | c9: 38 x8 + 37 x9 + 36 x10 + 35 x11 + 34 x12 + 33 x13 + 32 x14 + 31 x15 19 | <= 90 20 | c10: 28 x16 + 27 x17 + 26 x18 + 25 x19 + 24 x20 + 23 x21 + 22 x22 + 21 x23 21 | <= 70 22 | LB11: x0 + x1 + x2 - x3 - x4 + x5 - x6 + x7 - x8 - x9 + x10 + x11 + x12 + x13 23 | + x14 + x15 + x16 + x17 - x18 + x19 + x20 - x21 + x22 - x23 <= -4 24 | Bounds 25 | 0 <= x0 <= 1 26 | 0 <= x1 <= 1 27 | 0 <= x2 <= 1 28 | 0 <= x3 <= 1 29 | 0 <= x4 <= 1 30 | 0 <= x5 <= 1 31 | 0 <= x6 <= 1 32 | 0 <= x7 <= 1 33 | 0 <= x8 <= 1 34 | 0 <= x9 <= 1 35 | 0 <= x10 <= 1 36 | 0 <= x11 <= 1 37 | 0 <= x12 <= 1 38 | 0 <= x13 <= 1 39 | 0 <= x14 <= 1 40 | 0 <= x15 <= 1 41 | 0 <= x16 <= 1 42 | 0 <= x17 <= 1 43 | 0 <= x18 <= 1 44 | 0 <= x19 <= 1 45 | 0 <= x20 <= 1 46 | 0 <= x21 <= 1 47 | 0 <= x22 <= 1 48 | 0 <= x23 <= 1 49 | Binaries 50 | x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 51 | x17 x18 x19 x20 x21 x22 x23 52 | End 53 | -------------------------------------------------------------------------------- /GAPVS/GAPVS.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/GAPVS.exe -------------------------------------------------------------------------------- /GAPVS/GAPVS.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30309.148 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GAPVS", "GAPVS.vcxproj", "{7AC774D6-BE3A-4F3D-B304-08121A42886F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Debug|x64.ActiveCfg = Debug|x64 17 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Debug|x64.Build.0 = Debug|x64 18 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Debug|x86.ActiveCfg = Debug|Win32 19 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Debug|x86.Build.0 = Debug|Win32 20 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Release|x64.ActiveCfg = Release|x64 21 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Release|x64.Build.0 = Release|x64 22 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Release|x86.ActiveCfg = Release|Win32 23 | {7AC774D6-BE3A-4F3D-B304-08121A42886F}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {B2289048-4DBA-44D6-85B3-2E3E34D7A993} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /GAPVS/GAPVS.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {7AC774D6-BE3A-4F3D-B304-08121A42886F} 23 | Win32Proj 24 | GAPVS 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v143 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v143 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v143 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v143 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | %(AdditionalIncludeDirectories) 92 | MultiThreadedDebugDLL 93 | Disabled 94 | Default 95 | 96 | 97 | Console 98 | true 99 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 100 | cplex1280.lib;%(AdditionalDependencies) 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | WIN64;_CONSOLE;IL_STD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 112 | $(CPLEX_STUDIO_DIR221)\cplex\include;$(CPLEX_STUDIO_DIR221)\concert\include 113 | MultiThreadedDLL 114 | 115 | 116 | Console 117 | true 118 | %(AdditionalLibraryDirectories) 119 | $(CPLEX_STUDIO_DIR221)\cplex\lib\x64_windows_msvc14\stat_mda\cplex2210.lib;$(CPLEX_STUDIO_DIR221)\cplex\lib\x64_windows_msvc14\stat_mda\ilocplex.lib;$(CPLEX_STUDIO_DIR221)\concert\lib\x64_windows_msvc14\stat_mda\concert.lib;%(AdditionalDependencies) 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE 131 | MultiThreadedDLL 132 | %(AdditionalIncludeDirectories) 133 | Neither 134 | 135 | 136 | Console 137 | true 138 | true 139 | true 140 | cplex1263.lib;%(AdditionalDependencies) 141 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 142 | 143 | 144 | 145 | 146 | Level3 147 | 148 | 149 | MaxSpeed 150 | true 151 | true 152 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 153 | 154 | 155 | Console 156 | true 157 | true 158 | true 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /GAPVS/GAPVS.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files 74 | 75 | 76 | Header Files 77 | 78 | 79 | Header Files 80 | 81 | 82 | Header Files 83 | 84 | 85 | Header Files 86 | 87 | 88 | Header Files 89 | 90 | 91 | Header Files 92 | 93 | 94 | Header Files 95 | 96 | 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | Source Files 109 | 110 | 111 | Source Files 112 | 113 | 114 | Source Files 115 | 116 | 117 | Source Files 118 | 119 | 120 | Source Files 121 | 122 | 123 | Source Files 124 | 125 | 126 | Source Files 127 | 128 | 129 | Source Files 130 | 131 | 132 | Source Files 133 | 134 | 135 | Source Files 136 | 137 | 138 | Source Files 139 | 140 | 141 | Source Files 142 | 143 | 144 | Source Files 145 | 146 | 147 | Source Files 148 | 149 | 150 | Source Files 151 | 152 | 153 | Source Files 154 | 155 | 156 | Source Files 157 | 158 | 159 | Source Files 160 | 161 | 162 | Source Files 163 | 164 | 165 | Source Files 166 | 167 | 168 | Source Files 169 | 170 | 171 | Source Files 172 | 173 | 174 | Source Files 175 | 176 | 177 | -------------------------------------------------------------------------------- /GAPVS/GAPVS128.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {7AC774D6-BE3A-4F3D-B304-08121A42886F} 23 | Win32Proj 24 | GAPVS 25 | 10.0.17763.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v141 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | %(AdditionalIncludeDirectories) 92 | MultiThreadedDebugDLL 93 | Disabled 94 | Default 95 | 96 | 97 | Console 98 | true 99 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 100 | cplex1280.lib;%(AdditionalDependencies) 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | WIN64;_CONSOLE;IL_STD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 112 | $(CPLEX_STUDIO_DIR128)\cplex\include;$(CPLEX_STUDIO_DIR128)\concert\include 113 | MultiThreadedDLL 114 | 115 | 116 | Console 117 | true 118 | %(AdditionalLibraryDirectories) 119 | $(CPLEX_STUDIO_DIR128)\cplex\lib\x64_windows_vs2017\stat_mda\cplex1280.lib;$(CPLEX_STUDIO_DIR128)\cplex\lib\x64_windows_vs2017\stat_mda\ilocplex.lib;$(CPLEX_STUDIO_DIR128)\concert\lib\x64_windows_vs2017\stat_mda\concert.lib;%(AdditionalDependencies) 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE 131 | MultiThreadedDLL 132 | %(AdditionalIncludeDirectories) 133 | Neither 134 | 135 | 136 | Console 137 | true 138 | true 139 | true 140 | cplex1263.lib;%(AdditionalDependencies) 141 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 142 | 143 | 144 | 145 | 146 | Level3 147 | 148 | 149 | MaxSpeed 150 | true 151 | true 152 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 153 | 154 | 155 | Console 156 | true 157 | true 158 | true 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /GAPVS/GAPVS129.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {7AC774D6-BE3A-4F3D-B304-08121A42886F} 23 | Win32Proj 24 | GAPVS 25 | 10.0.17763.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | %(AdditionalIncludeDirectories) 92 | MultiThreadedDebugDLL 93 | Disabled 94 | Default 95 | 96 | 97 | Console 98 | true 99 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 100 | cplex1280.lib;%(AdditionalDependencies) 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | WIN64;_CONSOLE;IL_STD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 112 | $(CPLEX_STUDIO_DIR129)\cplex\include;$(CPLEX_STUDIO_DIR129)\concert\include 113 | MultiThreadedDLL 114 | 115 | 116 | Console 117 | true 118 | %(AdditionalLibraryDirectories) 119 | $(CPLEX_STUDIO_DIR129)\cplex\lib\x64_windows_vs2017\stat_mda\cplex1290.lib;$(CPLEX_STUDIO_DIR129)\cplex\lib\x64_windows_vs2017\stat_mda\ilocplex.lib;$(CPLEX_STUDIO_DIR129)\concert\lib\x64_windows_vs2017\stat_mda\concert.lib;%(AdditionalDependencies) 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE 131 | MultiThreadedDLL 132 | %(AdditionalIncludeDirectories) 133 | Neither 134 | 135 | 136 | Console 137 | true 138 | true 139 | true 140 | cplex1263.lib;%(AdditionalDependencies) 141 | C:\AAAToBackup\didattica\SistemiSupportoDecisioni\codice\GAPCplusplus;%(AdditionalLibraryDirectories) 142 | 143 | 144 | 145 | 146 | Level3 147 | 148 | 149 | MaxSpeed 150 | true 151 | true 152 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 153 | 154 | 155 | Console 156 | true 157 | true 158 | true 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /GAPVS/GAPdual.lp: -------------------------------------------------------------------------------- 1 | \ENCODING=ISO-8859-1 2 | \Problem name: GAPinst 3 | 4 | Maximize 5 | obj1: w'0 + w'1 + w'2 + w'3 + w'4 + w'5 + w'6 + w'7 + 90 w''8 + 70 w''9 6 | Subject To 7 | c0: w'0 + 38 w''8 <= 22 8 | c1: w'1 + 37 w''8 <= 24 9 | c2: w'2 + 36 w''8 <= 26 10 | c3: w'3 + 35 w''8 <= 28 11 | c4: w'4 + 34 w''8 <= 30 12 | c5: w'5 + 33 w''8 <= 32 13 | c6: w'6 + 32 w''8 <= 34 14 | c7: w'7 + 31 w''8 <= 36 15 | c8: w'0 + 28 w''9 <= 60 16 | c9: w'1 + 27 w''9 <= 64 17 | c10: w'2 + 26 w''9 <= 68 18 | c11: w'3 + 25 w''9 <= 72 19 | c12: w'4 + 24 w''9 <= 76 20 | c13: w'5 + 23 w''9 <= 80 21 | c14: w'6 + 22 w''9 <= 84 22 | c15: w'7 + 21 w''9 <= 88 23 | Bounds 24 | w'0 >= 2.2250738585072e-308 25 | w'1 >= 2.2250738585072e-308 26 | w'2 >= 2.2250738585072e-308 27 | w'3 >= 2.2250738585072e-308 28 | w'4 >= 2.2250738585072e-308 29 | w'5 >= 2.2250738585072e-308 30 | w'6 >= 2.2250738585072e-308 31 | w'7 >= 2.2250738585072e-308 32 | 2.2250738585072e-308 <= w''8 <= 0 33 | 2.2250738585072e-308 <= w''9 <= 0 34 | End 35 | -------------------------------------------------------------------------------- /GAPVS/GAPmaster.lp: -------------------------------------------------------------------------------- 1 | \ENCODING=ISO-8859-1 2 | \Problem name: GAPinst 3 | 4 | Minimize 5 | obj1: z 6 | Subject To 7 | z0: z - 10 x1 - 11 x2 - 12 x3 - 13 x4 - 14 x5 - 15 x6 - 16 x7 - 17 x8 >= 0 8 | c1: 48 x1 + 47 x2 + 46 x3 + 45 x4 + 44 x5 + 43 x6 + 42 x7 + 41 x8 <= 160 9 | B2: z >= 0 10 | Bounds 11 | 0 <= x1 <= 1 12 | 0 <= x2 <= 1 13 | 0 <= x3 <= 1 14 | 0 <= x4 <= 1 15 | 0 <= x5 <= 1 16 | 0 <= x6 <= 1 17 | 0 <= x7 <= 1 18 | 0 <= x8 <= 1 19 | End 20 | -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.iobj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.iobj -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.ipdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.ipdb -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/CL.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/CL.command.1.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/CL.read.1.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/CL.write.1.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/GAPVS.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=8.1 2 | Release|Win32|C:\AAAToBackup\ricerche\GAP\GAPCplusplus\GAPVS\| 3 | -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/GAPVS.write.1u.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/GAPVS.write.1u.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/link.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/link.command.1.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/link.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/link.read.1.tlog -------------------------------------------------------------------------------- /GAPVS/Release/GAPVS.tlog/link.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/Release/GAPVS.tlog/link.write.1.tlog -------------------------------------------------------------------------------- /GAPVS/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "SA" : { "maxT" : 200, 3 | "k" : 0.5, 4 | "alpha" : 0.99, 5 | "iterAnneal" : 500, 6 | "coefAnneal" : 0.9, 7 | "maxiter" : 10000, 8 | "fGoMath" : 1 9 | }, 10 | "TS" : { "Ttenure" : 2, 11 | "maxiter" : 10000, 12 | "fGoMath" : 1 13 | }, 14 | "GA" : { "pc" : 1.0, 15 | "numpop" : 20, 16 | "maxiter" : 50 17 | }, 18 | "EC" : { "maxiter" : 50 19 | }, 20 | "ILS": { "maxiter" : 5000, 21 | "alpha" : 0.2 22 | }, 23 | "GRASP": { "maxiter" : 5000, 24 | "candNum" : 2 25 | }, 26 | "VNS": { "maxiter" : 500, 27 | "fGoMath" : 1 28 | }, 29 | "ACO": { "maxiter" : 20, 30 | "numpop" : 15, 31 | "alpha" : 0.3 32 | }, 33 | "SS": { "maxiter" : 5, 34 | "numpop" : 10, 35 | "alpha" : 0.4 36 | }, 37 | "lagrAss" : { "alpha" : 2.5, 38 | "alphastep" : 0.97, 39 | "minalpha" : 0.001, 40 | "innerIter" : 40, 41 | "maxiter" : 1000000 42 | }, 43 | "lagrCap" : { "alpha" : 2.5, 44 | "alphastep" : 0.9, 45 | "minalpha" : 0.001, 46 | "innerIter" : 40, 47 | "maxiter" : 1000000 48 | }, 49 | "RINS" :{ "maxnodes" : 5000 50 | }, 51 | "beam" :{ "delta" : 5, 52 | "maxnodes" : 200000 53 | }, 54 | "FandB" :{ "delta" : 2, 55 | "maxnodes" : 5000 56 | }, 57 | "corridor" :{ "delta" : 4, 58 | "maxiter" : 5 59 | }, 60 | "locBranching" : { "k" : 4, 61 | "maxiter" : 5 62 | }, 63 | "benders" : { "maxiter" : 5 64 | }, 65 | "VLSN" : { "maxiter" : 2, 66 | "k" : 4 67 | }, 68 | "datafile" : "c:\\AAAToBackup\\ricerche\\GAP\\istanze\\instances\\fileList.txt", 69 | "outdir" : "outdir", 70 | "isverbose" : 1, 71 | "aversionf" : 2 72 | } -------------------------------------------------------------------------------- /GAPVS/x64/Release/GAPVS.tlog/CL.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/x64/Release/GAPVS.tlog/CL.command.1.tlog -------------------------------------------------------------------------------- /GAPVS/x64/Release/GAPVS.tlog/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/x64/Release/GAPVS.tlog/CL.read.1.tlog -------------------------------------------------------------------------------- /GAPVS/x64/Release/GAPVS.tlog/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/x64/Release/GAPVS.tlog/CL.write.1.tlog -------------------------------------------------------------------------------- /GAPVS/x64/Release/GAPVS.tlog/GAPVS.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=8.1 2 | Release|x64|C:\AAAToBackup\ricerche\GAP\GAPCplusplus\GAPVS\| 3 | -------------------------------------------------------------------------------- /GAPVS/x64/Release/GAPVS.tlog/unsuccessfulbuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVS/x64/Release/GAPVS.tlog/unsuccessfulbuild -------------------------------------------------------------------------------- /GAPVSC/cplex1263.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVSC/cplex1263.dll -------------------------------------------------------------------------------- /GAPVSC/cplex1263.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVSC/cplex1263.lib -------------------------------------------------------------------------------- /GAPVSC/cplex1290.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVSC/cplex1290.dll -------------------------------------------------------------------------------- /GAPVSC/cplex1290.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maniezzo/MatheuristicsGAP/304581fa7bbea0c3257e0e0c2c590d2b644337d4/GAPVSC/cplex1290.lib -------------------------------------------------------------------------------- /GAPVSC/makefile: -------------------------------------------------------------------------------- 1 | CXX = g++ 2 | CXXFLAGS = -g -Wall -O -Wreorder 3 | LDADD = 4 | 5 | OBJ = main.o ACO.o BeamSearch.o Benders.o ConstructHeu.o Controller.o Corridor.o Ejection.o ForwardBackward.o GAP.o GeneticAlgorithm.o json.o Kernel.o Lagrangian.o LocalSearch.o LocBranching.o LowerBound.o MetaLocalSearch.o MIPCplex.o MTHG.o Persistence.o Rins.o SimAnnealing.o TabuSearch.o VLSN.o 6 | 7 | %.o: ..\%.cpp 8 | $(CXX) $(CXXFLAGS) -c $^ -o $@ 9 | 10 | main: $(OBJ) 11 | $(CXX) $(CXXFLAGS) $(OBJ) -o GAPVS 12 | 13 | clean: 14 | rm -rf $(OBJ) GAPVS 15 | 16 | .PHONY: clean -------------------------------------------------------------------------------- /GAPVSC/matheuristics.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | }, 6 | { 7 | "path": ".." 8 | } 9 | ], 10 | "settings": {} 11 | } -------------------------------------------------------------------------------- /GeneticAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | #include "GeneticAlgorithm.h" 2 | 3 | GenAlgo::GenAlgo(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | GenAlgo::~GenAlgo() 15 | { 16 | //dtor 17 | } 18 | 19 | int GenAlgo::genAlgo(int** c, int maxiter, int numpop, double pc) 20 | { int z=0; 21 | int i,iter; 22 | vector fitness(numpop); 23 | vector pop(numpop),newpop(numpop); 24 | 25 | if( !initPop(pop, numpop, fitness) ) 26 | return NULL; 27 | 28 | Rins* RINS = new Rins(GAP,GAP->zub); // for crossover 29 | for(i=0;i& pop, int numpop, vector& fitness, Rins* RINS, int* newsol) 85 | { double r; 86 | int p1,p2; 87 | 88 | p1 = montecarlo(fitness); 89 | p2 = montecarlo(fitness); 90 | 91 | cout << "Mating " << p1 << " and " << p2 << endl; 92 | 93 | r = (double)rand() / RAND_MAX; 94 | if(r < GAP->conf->GA->pc) 95 | crossOver(pop,p1,p2,RINS,newsol); 96 | else 97 | newsol = pop[p1]; 98 | 99 | return; 100 | } 101 | 102 | int GenAlgo::montecarlo(vector& v) 103 | { double sum=0; 104 | unsigned int i; 105 | 106 | for(i=0;i= f) break; 115 | } 116 | return i; 117 | } 118 | 119 | // initialization of population and fitness 120 | bool GenAlgo::initPop(vector& pop, int numpop, vector& fitness) 121 | { 122 | int i,z; 123 | for (i=0; i cost(m),capleft(m),indReq(m),ind(n); 141 | auto compCost = [&cost](int a, int b){ return cost[a] < cost[b]; }; // ASC order, predecate for sort 142 | 143 | for(i=0;icap[i]; // residual capacities 144 | for(j=0;jreq[i][j]; // generalized cost for ordering 159 | indReq[i] = i; // server index for requests ordering 160 | } 161 | 162 | std::sort(indReq.begin(), indReq.end(), compCost); // sort by increasing gen cost 163 | k = std::rand() % 3; // random among candate set of best 3 164 | newsol[j] = indReq[k]; 165 | z += GAP->c[newsol[j]][j]; 166 | } 167 | 168 | if(abs(GAP->checkSol(newsol)-z) > GAP->EPS) 169 | { GAP->fixSol(newsol,&z); 170 | if(abs(GAP->checkSol(newsol)-z) > GAP->EPS) 171 | { numRetry++; 172 | if(numRetry < 5) 173 | goto l0; 174 | else if (numRetry < 10) 175 | { GAP->fixSolViaKnap(newsol,&z); 176 | if(abs(GAP->checkSol(newsol)-z) > GAP->EPS) 177 | goto l0; 178 | } 179 | else 180 | { 181 | cout << "[generateOneSol]: infeasible" << endl; 182 | newsol = nullptr; 183 | } 184 | } 185 | } 186 | cout << "[generateOneSol]: z = " << (*zval = z) << endl; 187 | 188 | return newsol; 189 | } 190 | 191 | // fixes common assignments and frees the rest 192 | void GenAlgo::crossOver(vector& pop, int p1, int p2, Rins* RINS, int* newsol) 193 | { int j,num=0,res; 194 | 195 | for(j=0;jdive( GAP->c, 207 | GAP->conf->rinsConf->maxnodes, 208 | INT_MAX, 209 | newsol, false 210 | ); 211 | 212 | cout << "Xover, cost " << res << endl; 213 | } 214 | 215 | -------------------------------------------------------------------------------- /GeneticAlgorithm.h: -------------------------------------------------------------------------------- 1 | #ifndef GENALG_H 2 | #define GENALG_H 3 | #include "GAP.h" 4 | #include "Rins.h" 5 | 6 | class GenAlgo 7 | { 8 | public: 9 | GeneralizedAssignemnt* GAP; 10 | 11 | GenAlgo(GeneralizedAssignemnt*, int&); 12 | ~GenAlgo(); 13 | int genAlgo(int**, int, int, double); 14 | 15 | private: 16 | // local mirrors 17 | int m,n; 18 | int *sol,*solbest; 19 | int** req; 20 | int & zub,zlb; 21 | 22 | // private functions 23 | bool initPop(vector&,int,vector&); 24 | int* generateOneSol(int*); 25 | void GenAlgo::selCrossover(vector& pop, int numpop, vector&,Rins* RINS, int*); 26 | bool mutate(vector& pop, int numpop); 27 | int GenAlgo::montecarlo(vector&); 28 | void GenAlgo::crossOver(vector& pop, int p1, int p2,Rins* RINS, int*); 29 | }; 30 | 31 | #endif // GENALG_H 32 | -------------------------------------------------------------------------------- /Kernel.cpp: -------------------------------------------------------------------------------- 1 | #include "Kernel.h" 2 | //#include /* visual memory leak for VS */ 3 | 4 | Kernel::Kernel(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 5 | { 6 | //ctor 7 | GAP = GAPinstance; 8 | m = GAP->m; 9 | n = GAP->n; 10 | sol = GAP->sol; 11 | solbest = GAP->solbest; 12 | req = GAP->req; 13 | } 14 | 15 | Kernel::~Kernel() 16 | { 17 | //dtor 18 | } 19 | 20 | int Kernel::solveByKernel(bool fVerbose, int numVarInBucket) 21 | { int i,j,ii,status,numCol,iter,nkinit,numKer=0,numNotLB,numBuckets,lastVar=0,numAdded; 22 | double zlb,z; 23 | vector x,d,dj; // milp primal, dual vars and red costs 24 | auto compRedCost = [&dj](double a, double b){ return dj[a] > dj[b]; }; // DESC order 25 | 26 | if(GAP->n == NULL) 27 | { cout << "Instance undefined. Exiting" << endl; 28 | return INT_MAX; 29 | } 30 | cout << "Kernel search, initial solution" << endl; 31 | isVerbose = fVerbose; 32 | 33 | int numRows,numCols,numNZrow; 34 | numRows = n+m; // num of constraints 35 | numCols = n*m; // num of variables 36 | numNZrow= n*m; // max num of nonzero values in a row 37 | vector kernel(n*m),lambda_i(n*m); 38 | vector indDj(n*m); 39 | MIPCplex* CPX = new MIPCplex(numRows,numCols,numNZrow); 40 | CPX->GAP = GAP; 41 | CPX->allocateMIP(isVerbose); 42 | 43 | try 44 | { iter = 0; 45 | status = CPX->solveMIP(false,false); // LP solution 46 | if ( status ) 47 | { cout << "[solveByKernel] Error" << endl; 48 | goto lend; 49 | } 50 | // reads the solution 51 | zlb = CPX->objval; 52 | cout << "iter "<< iter << " zlb " << zlb << endl; 53 | 54 | // primal variables (m*n) and reduced costs 55 | x.clear(); 56 | for(i=0;ix[i]); 58 | if(x[i]>0) 59 | { kernel[i] = true; // initial kernel 60 | lambda_i[i] = true; 61 | numKer++; 62 | } 63 | dj.push_back(CPX->dj[i]); // reduced costs (CPLEX naming!) 64 | indDj[i]=i; 65 | } 66 | nkinit = numKer; 67 | numNotLB = n*m-numKer; 68 | numBuckets = (int) (1.0*numNotLB/numVarInBucket + 0.999); 69 | //numVarInBucket = (int) ( 1.0*numNotLB / numBuckets + 0.999); 70 | 71 | // dual variables, assignments (n) and capacity (m). Here unused 72 | d.clear(); 73 | for(i=0;ipi[i]); 74 | std::sort(indDj.begin(), indDj.end(), compRedCost); // sort by increasing red costs 75 | 76 | CPXsetintparam(CPX->env,CPXPARAM_MIP_Display,0); // cplex output to screen 77 | do 78 | { 79 | updateModelWithKernel(CPX,lambda_i); 80 | CPXsetdblparam(CPX->env,CPXPARAM_MIP_Tolerances_UpperCutoff,zub); // cost cut 81 | status = CPX->solveMIP(true,false); // LP solution 82 | if ( status ) 83 | { cout << "[solveByKernel] No solution" << endl; 84 | z = DBL_MAX; 85 | } 86 | else 87 | { 88 | // reads the solution 89 | z = CPX->objval; 90 | if(zx[i]); 96 | if(CPX->x[i] && !kernel[i]) 97 | { kernel[i] = true; 98 | numKer++; 99 | cout << "variable " << i << " entering kernel" << endl; 100 | } 101 | } 102 | } 103 | 104 | for(int jj=0;jjfreeMIP(); 136 | delete(CPX); 137 | return 0; 138 | } 139 | 140 | // defines the vars that can enter the solution 141 | void Kernel::updateModelWithKernel(MIPCplex* CPX, vector lambda_i) 142 | { int i,j,isol,rand,status; 143 | vector lstKernel; 144 | 145 | for(i=0;ilb[i] == 0.0) // lb OK, only ub could be wrong 161 | { CPX->ub[i] = 1.0; 162 | bd[i] = 1.0; 163 | lu[i] = 'U'; // bd[j] is an upper bound 164 | } 165 | else // lb wrong, ub should be OK 166 | { CPX->lb[i] = 0.0; 167 | bd[i] = 0.0; 168 | lu[i] = 'L'; // bd[j] is an upper bound 169 | } 170 | } 171 | else // not in kernel, cannot be chosen 172 | { 173 | CPX->lb[i] = 0.0; // forbidding in the solution 174 | bd[i] = 0.0; 175 | lu[i] = 'B'; // bd[j] is the lower and upper bound 176 | } 177 | indices[i] = i; 178 | } 179 | cout << endl; 180 | 181 | status = CPXchgbds(CPX->env, CPX->lp, cnt, indices, lu, bd); 182 | delete[](indices); 183 | delete[](lu); 184 | delete[](bd); 185 | 186 | return; 187 | } 188 | -------------------------------------------------------------------------------- /Kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef KERNEL_H 2 | #define KERNEL_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include // std::find 9 | #include "MIPCplex.h" 10 | 11 | class Kernel 12 | { 13 | public: 14 | GeneralizedAssignemnt* GAP; 15 | 16 | Kernel(GeneralizedAssignemnt*, int&); 17 | ~Kernel(); 18 | int solveByKernel(bool fVerbose, int numBuckets); 19 | 20 | private: 21 | // local mirrors 22 | int m,n; 23 | int *sol,*solbest; 24 | int** req; 25 | int & zub,zlb; 26 | bool isVerbose; 27 | 28 | void updateModelWithKernel(MIPCplex* CPX, vector kernel); 29 | }; 30 | 31 | #endif // KERNEL_H 32 | -------------------------------------------------------------------------------- /Lagrangian.cpp: -------------------------------------------------------------------------------- 1 | #include "Lagrangian.h" 2 | #include "LocalSearch.h" 3 | 4 | Lagrangian::Lagrangian(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 5 | { 6 | //ctor 7 | GAP = GAPinstance; 8 | m = GAP->m; 9 | n = GAP->n; 10 | sol = GAP->sol; 11 | solbest = GAP->solbest; 12 | req = GAP->req; 13 | } 14 | 15 | Lagrangian::~Lagrangian() 16 | { 17 | //dtor 18 | } 19 | 20 | // Lagrangian, feasible for the assignments, relaxes capacities 21 | int Lagrangian::lagrAss(int** c, double alpha, double alphastep, double minAlpha, int innerIter, int maxiter) 22 | { int i,sumSubGrad2,iter=0,zcurr; 23 | double zlb,step=0,zlbBest,fakeZub; 24 | 25 | double* lambda = new double[m]; 26 | int* subgrad = new int[m]; 27 | int* lbsol = new int[n]; 28 | 29 | ofstream flog; 30 | flog.open ("lagr.log"); 31 | flog << fixed << setprecision(3); 32 | 33 | zcurr = INT_MAX; // initial upper bound 34 | zlb = DBL_MIN; 35 | zlbBest = DBL_MIN; 36 | for(i=0;i minAlpha && iter < maxiter) 42 | { lbsol = subproblem_ass(c, &zlb, &zlbBest, zub, lambda, subgrad); 43 | zcurr = GAP->checkSol(lbsol); 44 | 45 | if(zcurr == zlbBest || (zub-zlbBest) < 1.0) // -------------------------- Optimum found 46 | { cout << "[lagrAss] Found the optimum !!! zopt="<fixSolViaKnap(lbsol, &zcurr); // hope to fix infeasibilities 54 | GAP->fixSol(lbsol, &zcurr); 55 | if(zcurr < 10*zlb) 56 | { for(int j=0;jzub); 58 | LS->opt10(c, true); 59 | delete LS; 60 | } 61 | if(zcurr minAlpha && iter < maxiter) 168 | { subproblem_cap(c, &zlb, &zlbBest, zub, lambda, subgrad, lbsol); 169 | zcurr = GAP->checkSol(lbsol); 170 | 171 | if(zcurr == zlbBest || (zub-zlbBest) < 1.0) // -------------------------- Optimum found 172 | { cout << "[lagrCap] Found the optimum!!! zopt="<< zub << " zlb=" << zlbBest<fixSolViaKnap(lbsol, &zcurr); // hope to fix infeasibilities 181 | //GAP->fixSol(lbsol, &zcurr); 182 | if(zcurr < 10*zlb) 183 | { for(int j=0;jzub); 185 | LS->opt10(c, true); 186 | delete LS; 187 | } 188 | if(zcurrm; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | LocBranching::~LocBranching() 15 | { 16 | //dtor 17 | } 18 | 19 | int LocBranching::localBranching(int** c, int k, int maxiter, bool fVerbose) 20 | { int i,j,iter,status; 21 | int zubIter,zubOld=0; 22 | int* solIter = new int[n]; 23 | 24 | if(GAP->n == NULL) 25 | { cout << "Instance undefined. Exiting" << endl; 26 | return INT_MAX; 27 | } 28 | isVerbose = fVerbose; 29 | 30 | int numRows,numCols,numNZrow; 31 | numRows = n+m; // num of constraints 32 | numCols = n*m; // num of variables 33 | numNZrow= n*m; // max num of nonzero values in a row 34 | 35 | MIPCplex* CPX = new MIPCplex(numRows,numCols,numNZrow); 36 | CPX->GAP = GAP; 37 | CPX->allocateMIP(isVerbose); 38 | for(j=0;jx[i*n+j] << "\t"; 62 | cout << endl; 63 | } 64 | } 65 | // reads the solution 66 | zubIter = 0; 67 | for(j=0;jx[i*n+j] > 0.5) 70 | { solIter[j] = i; 71 | break; 72 | } 73 | zubIter += c[solIter[j]][j]; 74 | } 75 | 76 | if(abs(zubIter - GAP->checkSol(solIter)) > GAP->EPS) 77 | cout << "[localBranching] No feasible solution at this iteration" << endl; 78 | else 79 | { cout << "[localBranching] iter "<< iter <<" zubIter "<< zubIter << endl; 80 | if(isVerbose) 81 | { cout << "Solution: "; for(j=0;jenv, CPX->lp); 96 | status = CPXdelrows(CPX->env, CPX->lp, numRows-1, numRows-1); 97 | } 98 | } 99 | } 100 | } 101 | catch(std::exception const& e) 102 | { cout << "Error: " << e.what() << endl; 103 | goto lend; 104 | } 105 | 106 | lend: 107 | CPX->freeMIP(); 108 | delete(CPX); 109 | delete(solIter); 110 | return zub; 111 | } 112 | 113 | // adds a local branching cut 114 | void LocBranching::addLBcut(MIPCplex* CPX, int* solIter, int k) 115 | { int i,j,isol; 116 | int idRow=0,numRows=1,numNZrow=n*m; 117 | 118 | int * rmatbeg = (int *) malloc ((numRows+1) * sizeof(int)); 119 | int * rmatind = (int *) malloc (numNZrow * sizeof(int)); 120 | double * rmatval = (double *) malloc (numNZrow * sizeof(double)); 121 | double * rhs = (double *) malloc (numRows * sizeof(double)); 122 | char * sense = (char *) malloc (numRows * sizeof(char)); 123 | char** rowname = (char **) malloc (numRows * sizeof(char*)); 124 | rowname[0] = (char *) malloc(sizeof(char) * (11)); // there will be only one row 125 | 126 | numNZrow = 0; // number of nonzero elements in the row to add 127 | rmatbeg[0] = 0; 128 | sense[0] = 'L'; 129 | rhs[0] = k; 130 | sprintf(rowname[0],"%s%d","LB",CPX->numRows); 131 | for(j=0;jn*i; 137 | rmatval[numNZrow] = -1; // termine (1-x_j) 138 | numNZrow++; 139 | rhs[0] -= 1; 140 | } 141 | else 142 | { rmatind[numNZrow] = j+GAP->n*i; 143 | rmatval[numNZrow] = 1; // termine x_j 144 | numNZrow++; 145 | } 146 | } 147 | 148 | rmatbeg[1] = numNZrow; 149 | int status = CPXaddrows (CPX->env, CPX->lp, 0, 1, numNZrow, rhs, sense, rmatbeg, rmatind, rmatval, NULL, rowname); 150 | if ( status ) goto TERMINATE; 151 | idRow++; 152 | 153 | TERMINATE: 154 | if(rmatbeg != NULL) free(rmatbeg); 155 | if(rmatind != NULL) free(rmatind); 156 | if(rmatval != NULL) free(rmatval); 157 | if(rhs != NULL) free(rhs); 158 | if(sense != NULL) free(sense); 159 | if (rowname!=NULL) 160 | { free(*rowname); 161 | free(rowname); 162 | } 163 | return; 164 | } 165 | 166 | 167 | -------------------------------------------------------------------------------- /LocBranching.h: -------------------------------------------------------------------------------- 1 | #ifndef LOCBRANCH_H 2 | #define LOCBRANCH_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include // std::find 9 | #include "MIPCplex.h" 10 | 11 | class LocBranching 12 | { 13 | public: 14 | GeneralizedAssignemnt* GAP; 15 | 16 | LocBranching(GeneralizedAssignemnt*, int&); 17 | ~LocBranching(); 18 | int localBranching(int** c, int k, int maxiter, bool fVerbose); 19 | 20 | private: 21 | // local mirrors 22 | int m,n; 23 | int *sol,*solbest; 24 | int** req; 25 | int & zub,zlb; 26 | bool isVerbose; 27 | 28 | void addLBcut(MIPCplex* CPX, int* solIter, int k); // adds a local branching cut 29 | }; 30 | 31 | #endif // LOCBRANCH_H 32 | -------------------------------------------------------------------------------- /LocalSearch.cpp: -------------------------------------------------------------------------------- 1 | #include "LocalSearch.h" 2 | 3 | LocalSearch::LocalSearch(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | LocalSearch::~LocalSearch() 15 | { 16 | //dtor 17 | } 18 | 19 | // tries each client with each other facility 20 | int LocalSearch::opt10(int** c, bool isOriginal) 21 | { int z=0,zorg; 22 | int i, isol, j; 23 | vector capleft(m); 24 | 25 | for(i=0;icap[i]; 26 | for (j = 0; j < n; j++) 27 | { capleft[sol[j]] -= req[sol[j]][j]; 28 | z += c[sol[j]][j]; 29 | } 30 | zorg=z; 31 | 32 | l0: 33 | for (j = 0; j < n; j++) 34 | { 35 | isol = sol[j]; 36 | for (i = 0; i < m; i++) 37 | { 38 | if (i == isol) continue; 39 | if (c[i][j] < c[isol][j] && capleft[i] >= req[i][j]) 40 | { // remove from isol and assign to i 41 | sol[j] = i; 42 | capleft[i] -= req[i][j]; 43 | capleft[isol] += req[isol][j]; 44 | z -= (c[isol][j] - c[i][j]); 45 | if(isOriginal && zstoreBest(sol,z); 47 | cout << "[1-0 opt] new zub " << zub << endl; 48 | } 49 | goto l0; 50 | } 51 | } 52 | } 53 | //if(z capleft(m); 63 | 64 | for(i=0;icap[i]; 65 | for (j = 0; j < n; j++) 66 | { capleft[sol[j]] -= req[sol[j]][j]; 67 | z += c[sol[j]][j]; 68 | } 69 | zcheck = GAP->checkSol(sol); 70 | zorg = z; 71 | 72 | l0: 73 | for(j1=0;j1 0) 77 | { cap1 = capleft[sol[j1]] + req[sol[j1]][j1] - req[sol[j1]][j2]; 78 | cap2 = capleft[sol[j2]] + req[sol[j2]][j2] - req[sol[j2]][j1]; 79 | if(cap1>=0 && cap2 >=0) 80 | { capleft[sol[j1]] += req[sol[j1]][j1] - req[sol[j1]][j2]; 81 | capleft[sol[j2]] += req[sol[j2]][j2] - req[sol[j2]][j1]; 82 | temp = sol[j1]; 83 | sol[j1] = sol[j2]; 84 | sol[j2] = temp; 85 | z -= delta; 86 | zcheck = GAP->checkSol(sol); 87 | if(isOriginal) 88 | if(abs(z-zcheck) > GAP->EPS) 89 | cout << "[1-1] ohi" << endl; 90 | else if(z GAP->EPS) 105 | cout << "[1.1opt] Ahi ahi" << endl; 106 | zcheck = GAP->checkSol(sol); 107 | //if (z < zorg) 108 | // cout << "2opt improved" << endl; 109 | return z; 110 | } 111 | 112 | // a neighbor 21 at random, swap 2 (same depot) vs 1 (other depot) 113 | void LocalSearch::neigh21() 114 | { int i,i1,i2,j,j11,j12,j21,iter; 115 | vector lst1, lst2; 116 | vector capleft(m); 117 | int zcheck; 118 | 119 | 120 | for(i=0;icap[i]; 121 | for (j = 0; j < n; j++) 122 | capleft[sol[j]] -= req[sol[j]][j]; 123 | 124 | i1 = rand()%m; 125 | i2 = rand()%m; 126 | if(i1==i2) 127 | i2 = (i2+1) % m; 128 | 129 | for(j=0;j= 0) && 149 | ((capleft[i2]-req[i2][j11]-req[i2][j12]+req[i2][j21]) >= 0) ) 150 | { sol[j11]=i2; 151 | sol[j12]=i2; 152 | sol[j21]=i1; 153 | zcheck = GAP->checkSol(sol); 154 | if(zcheck == INT_MAX) 155 | cout << "[2-1] ohi" << endl; 156 | } 157 | else // try another, maybe feasible, neighbor 158 | { iter++; 159 | if(iter < 50) 160 | goto loop; 161 | } 162 | //if(iter<50) cout << "swap 21 ok" << endl; 163 | 164 | return; 165 | } 166 | -------------------------------------------------------------------------------- /LocalSearch.h: -------------------------------------------------------------------------------- 1 | #ifndef LOCALSEARCH_H 2 | #define LOCALSEARCH_H 3 | #include "GAP.h" 4 | 5 | class LocalSearch 6 | { 7 | public: 8 | GeneralizedAssignemnt* GAP; 9 | 10 | LocalSearch(GeneralizedAssignemnt*, int&); 11 | ~LocalSearch(); 12 | int opt10(int**,bool); 13 | double opt11(int**,bool); 14 | void neigh21(); 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | }; 23 | 24 | #endif // LOCALSEARCH_H 25 | -------------------------------------------------------------------------------- /LowerBound.cpp: -------------------------------------------------------------------------------- 1 | #include "LowerBound.h" 2 | #include "LocalSearch.h" 3 | #include "Benders.h" 4 | 5 | LowerBound::LowerBound(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 6 | { 7 | //ctor 8 | GAP = GAPinstance; 9 | m = GAP->m; 10 | n = GAP->n; 11 | sol = GAP->sol; 12 | solbest = GAP->solbest; 13 | req = GAP->req; 14 | } 15 | 16 | LowerBound::~LowerBound() 17 | { 18 | //dtor 19 | } 20 | 21 | // each at its nearest facility 22 | double LowerBound::trivialBound() 23 | { int i,j,m,n; 24 | double lb=0,minc,mini; 25 | 26 | m = GAP->m; 27 | n = GAP->n; 28 | 29 | for(j=0;jc[i][j] < minc) 33 | { minc = GAP->c[i][j]; 34 | mini = i; 35 | } 36 | lb += minc; 37 | } 38 | 39 | cout << "Trivial bound: "<< lb << endl; 40 | return lb; 41 | } 42 | 43 | double LowerBound::linearBound() 44 | { double lb; 45 | int numRows,numCols,numNZrow; 46 | int i,j,n,m; 47 | numRows = GAP->n+GAP->m; // num of constraints 48 | numCols = GAP->n*GAP->m; // num of variables 49 | numNZrow= GAP->n*GAP->m; // max num of nonzero values in a row 50 | n = GAP->n; 51 | m = GAP->m; 52 | CPX = new MIPCplex(numRows,numCols,numNZrow); 53 | CPX->GAP = GAP; 54 | CPX->allocateMIP(true); // verbose output 55 | int statusMIP = CPX->solveMIP(false,false); 56 | if(statusMIP == 0) 57 | { lb = CPX->objval; 58 | cout << "Linear bound: "<< lb << endl; 59 | if(n*m < 101) // print LP if instance is small 60 | { cout << " - Solution: " << endl; 61 | for (i = 0; i < m; ++i) 62 | { cout << " " << i << ": "; 63 | for (j = 0; j < n; ++j) 64 | cout << CPX->x[i*n+j] << "\t"; 65 | cout << endl; 66 | } 67 | } 68 | } 69 | else 70 | lb = DBL_MAX; 71 | CPX->freeMIP(); 72 | 73 | delete CPX; 74 | return lb; 75 | } 76 | 77 | double LowerBound::linearBound(int** c, int n, int m, int** req, int* cap) 78 | { double lb; 79 | int numRows,numCols,numNZrow; 80 | int i,j; 81 | bool isVerbose = false; 82 | numRows = n+m; // num of constraints 83 | numCols = n*m; // num of variables 84 | numNZrow= n*m; // max num of nonzero values in a row 85 | CPX = new MIPCplex(numRows,numCols,numNZrow); 86 | CPX->GAP = GAP; 87 | CPX->allocateMIP(c, n, m, req, cap, isVerbose); // linear bound, verbose output 88 | int statusMIP = CPX->solveMIP(false,false); 89 | if(statusMIP == 0) 90 | { lb = CPX->objval; 91 | if(isVerbose) 92 | { cout << "Linear bound: "<< lb << endl; 93 | if(n*m < 101) // print LP if instance is small 94 | { cout << " - Solution: " << endl; 95 | for (i = 0; i < m; ++i) 96 | { cout << " " << i << ": "; 97 | for (j = 0; j < n; ++j) 98 | cout << CPX->x[i*n+j] << "\t"; 99 | cout << endl; 100 | } 101 | } 102 | } 103 | } 104 | else 105 | lb = DBL_MAX; 106 | CPX->freeMIP(); 107 | 108 | delete CPX; 109 | return lb; 110 | } 111 | 112 | vector LowerBound::linearBound(int** c, int n, int m, int** req, int* cap, double* lb) 113 | { 114 | vector x(n*m,0); 115 | int numRows, numCols, numNZrow; 116 | int i,j; 117 | bool isVerbose = false; 118 | numRows = n + m; // num of constraints 119 | numCols = n * m; // num of variables 120 | numNZrow = n * m; // max num of nonzero values in a row 121 | CPX = new MIPCplex(numRows, numCols, numNZrow); 122 | CPX->GAP = GAP; 123 | CPX->allocateMIP(c, n, m, req, cap, isVerbose); // linear bound, verbose output 124 | int statusMIP = CPX->solveMIP(false, false); 125 | if (statusMIP == 0) 126 | { 127 | *lb = CPX->objval; 128 | for (i = 0; i < m; ++i) 129 | for (j = 0; j < n; ++j) 130 | x[i*n + j] = CPX->x[i*n + j]; 131 | } 132 | else 133 | *lb = DBL_MAX; 134 | CPX->freeMIP(); 135 | 136 | delete CPX; 137 | return x; 138 | } 139 | 140 | double LowerBound::lagrangianDecomposition(int** c, double alpha, double alphastep, double minAlpha, int innerIter, int maxiter) 141 | { int i,j,iter=0,zcurr; 142 | double zlb,step=0,zlbBest=0,fakeZub,sumSubGrad2; 143 | int* lbsol = new int[n]; 144 | 145 | vector< vector > x,y; 146 | vector< vector > lambda,subgrad; 147 | //from empty 2D-matrix of size (0,0) to m*n, initialized with 0s: 148 | x.resize( m , vector( n , 0 ) ); 149 | y.resize( m , vector( n , 0 ) ); 150 | lambda.resize( m , vector( n , 0 ) ); 151 | subgrad.resize( m , vector( n , 0 ) ); 152 | 153 | zcurr = INT_MAX; // initial upper bound 154 | zlb = DBL_MIN; 155 | 156 | iter = 0; 157 | while(alpha > minAlpha && iter < maxiter) 158 | { lbsol = subproblem_LD(c, &zlb, &zlbBest, zub, lambda, subgrad, x, y); 159 | zcurr = GAP->checkSol(lbsol); 160 | 161 | if(zcurr == zlbBest || (zub-zlbBest) < 1.0) // -------------------------- Optimum found 162 | { cout << "[lagrCap] Found the optimum!!! zopt="<< zub << " zlb=" << zlbBest<fixSolViaKnap(lbsol, &zcurr); // hope to fix infeasibilities 170 | //GAP->fixSol(lbsol, &zcurr); 171 | if(zcurr < 10*zlb) 172 | { for(int j=0;jzub); 174 | LS->opt10(c, true); 175 | delete LS; 176 | } 177 | if(zcurr linearBound(int** c, int n, int m, int** req, int* cap, double* lb); 19 | double lagrangianDecomposition(int** c, double alpha, double alphastep, double minAlpha, int innerIter, int maxiter); 20 | double benders(); 21 | 22 | private: 23 | int* subproblem_LD(int**, double*, double*, int, vector>&, 24 | vector>&, 25 | vector>&, 26 | vector>&); 27 | 28 | // local mirrors 29 | int m,n; 30 | int *sol,*solbest; 31 | int** req; 32 | int & zub; 33 | }; 34 | 35 | #endif // LOWERBOUND_H 36 | -------------------------------------------------------------------------------- /MIPCplex.h: -------------------------------------------------------------------------------- 1 | #ifndef CPLEX_H 2 | #define CPLEX_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct loginfo 10 | { 11 | double lastincumbent; 12 | int* lastsol; 13 | int lastlog; 14 | int numcols; 15 | }; 16 | typedef struct loginfo LOGINFO, *LOGINFOptr; 17 | 18 | class MIPCplex 19 | { 20 | public: 21 | GeneralizedAssignemnt* GAP; 22 | 23 | MIPCplex(); 24 | MIPCplex(int, int, int); 25 | ~MIPCplex(); 26 | 27 | int numRows; 28 | int numCols; 29 | int numNZ; 30 | 31 | int status; 32 | double* obj; 33 | double* lb; 34 | double* ub; 35 | int* rmatbeg; 36 | int* rmatind; 37 | double* rmatval; 38 | double* rhs; 39 | char* sense; 40 | char* ctype; 41 | char* lptype; 42 | char** colname; 43 | char** rowname; 44 | double* x; // cplex solution vector 45 | double objval; 46 | double* pi; 47 | double* slack; 48 | double* dj; 49 | 50 | int allocateMIP(bool isVerbose); 51 | int allocateMIP(int** c, int n, int m, int** req, int* cap, bool isVerbose); 52 | int allocateDual(int, int, vector xbar, bool isVerbose); 53 | int freeMIP(); 54 | int solveMIP(bool fMIPint, bool fVerbose); 55 | void fixVariables(MIPCplex* CPX, vector fixVal); 56 | CPXENVptr env; 57 | CPXLPptr lp; 58 | 59 | private: 60 | int solstat; 61 | int *xbest; 62 | 63 | //int populatebycolumn (CPXENVptr env, CPXLPptr lp); 64 | int populatebyrow (CPXENVptr, CPXLPptr); 65 | int populatebyrow (CPXENVptr env, CPXLPptr lp, int** c, int n, int m, int** req, int* cap); 66 | int populateDual(CPXENVptr env, CPXLPptr lp, vector, int, int); 67 | }; 68 | 69 | #endif // CPLEX_H 70 | -------------------------------------------------------------------------------- /MTHG.h: -------------------------------------------------------------------------------- 1 | #ifndef MTHG_H 2 | #define MTHG_H 3 | #include "GAP.h" 4 | 5 | class MTHG 6 | { 7 | public: 8 | GeneralizedAssignemnt* GAP; 9 | 10 | MTHG(GeneralizedAssignemnt*, int&); 11 | ~MTHG(); 12 | int run_mthg(); 13 | 14 | private: 15 | int mthg_(int *n, int *m, int *p, int *w, int *c__, int minmax, int *z__, int *xstar, int jck); 16 | int gha_(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); 17 | int feas_(int *, int *, int *, int *, int *, int *, int *, int *, int *); 18 | int trin_(int *, int *, int *, int *, int *, int *, int *); 19 | int ghbcd_(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, double *, int *); 20 | int chmthg_(int *, int *, int *, int *, int *, int *, int *, int *); 21 | 22 | // local mirrors 23 | int m,n; 24 | int *sol,*solbest; 25 | int** req; 26 | int & zub,zlb; 27 | }; 28 | 29 | #endif // MTHG_H 30 | -------------------------------------------------------------------------------- /MetaLocalSearch.h: -------------------------------------------------------------------------------- 1 | #ifndef METALOCALSEARCH_H 2 | #define METALOCALSEARCH_H 3 | #include "GAP.h" 4 | #include "LocalSearch.h" 5 | #include "VLSN.h" 6 | #include "LowerBound.h" 7 | 8 | class MetaLocalSearch 9 | { 10 | public: 11 | GeneralizedAssignemnt* GAP; 12 | 13 | MetaLocalSearch(GeneralizedAssignemnt*, LocalSearch*, int&); 14 | ~MetaLocalSearch(); 15 | int iteratedLocSearch(int**,int,double); 16 | double MetaLocalSearch::GRASP(int maxIter, int candNum); 17 | double MetaLocalSearch::VNS(int maxIter, bool isMatheuristic); 18 | double MetaLocalSearch::VNSbasic(int maxIter); 19 | 20 | private: 21 | LocalSearch* LS; 22 | LowerBound* LB; 23 | void dataPerturbation(int**,int**,double); 24 | double MetaLocalSearch::GRASPcontruct(int candNum, bool isMatheuristic); 25 | 26 | // local mirrors 27 | int m,n; 28 | int *sol,*solbest; 29 | int** req; 30 | int & zub,zlb; 31 | }; 32 | 33 | #endif // METALOCALSEARCH_H 34 | -------------------------------------------------------------------------------- /Persistence.cpp: -------------------------------------------------------------------------------- 1 | #include "Persistence.h" 2 | #include 3 | 4 | Persistence::Persistence() 5 | { 6 | //ctor 7 | } 8 | 9 | Persistence::~Persistence() 10 | { 11 | //dtor 12 | } 13 | 14 | // loading parameters of all supported algorithms 15 | Config* Persistence::loadConfig() 16 | { 17 | string infile,line; 18 | 19 | infile = "config.json"; 20 | cout << "Opening " << infile << endl; 21 | 22 | ifstream jData (infile.c_str()); 23 | std::stringstream buffer; 24 | buffer << jData.rdbuf(); 25 | line = buffer.str(); 26 | //std::getline(jData,line); 27 | jData.close(); 28 | 29 | json::Value JSV = json::Deserialize(line); 30 | 31 | json::Object jSA = JSV["SA"]; 32 | GAP->conf->SA->maxT = (int) jSA["maxT"]; 33 | GAP->conf->SA->k = jSA["k"]; 34 | GAP->conf->SA->alpha = jSA["alpha"]; 35 | GAP->conf->SA->iterAnneal = jSA["iterAnneal"]; 36 | GAP->conf->SA->coefAnneal = jSA["coefAnneal"]; 37 | GAP->conf->SA->maxiter = jSA["maxiter"]; 38 | GAP->conf->SA->fGoMath = jSA["fGoMath"]; 39 | 40 | json::Object jTS = JSV["TS"]; 41 | GAP->conf->TS->Ttenure = jTS["Ttenure"]; 42 | GAP->conf->TS->maxiter = jTS["maxiter"]; 43 | GAP->conf->TS->fGoMath = jTS["fGoMath"]; 44 | 45 | json::Object jILS = JSV["ILS"]; 46 | GAP->conf->IterLS->maxiter = jILS["maxiter"]; 47 | GAP->conf->IterLS->alpha = jILS["alpha"]; 48 | 49 | json::Object jGRASP = JSV["GRASP"]; 50 | GAP->conf->GRASP->maxiter = jGRASP["maxiter"]; 51 | GAP->conf->GRASP->candNum = jGRASP["candNum"]; 52 | 53 | json::Object jVNS = JSV["VNS"]; 54 | GAP->conf->VNS->maxiter = jVNS["maxiter"]; 55 | GAP->conf->VNS->fGoMath = jVNS["fGoMath"]; 56 | 57 | json::Object jGA = JSV["GA"]; 58 | GAP->conf->GA->maxiter = jGA["maxiter"]; 59 | GAP->conf->GA->numpop = jGA["numpop"]; 60 | GAP->conf->GA->pc = jGA["pc"]; 61 | 62 | json::Object jACO = JSV["ACO"]; 63 | GAP->conf->ACO->maxiter = jACO["maxiter"]; 64 | GAP->conf->ACO->numpop = jACO["numpop"]; 65 | GAP->conf->ACO->alpha = jACO["alpha"]; 66 | 67 | json::Object jSS = JSV["SS"]; 68 | GAP->conf->SS->maxiter = jSS["maxiter"]; 69 | GAP->conf->SS->numpop = jSS["numpop"]; 70 | GAP->conf->SS->alpha = jSS["alpha"]; 71 | 72 | json::Object jEC = JSV["EC"]; 73 | GAP->conf->EC->maxiter = jEC["maxiter"]; 74 | 75 | json::Object jLagrAss = JSV["lagrAss"]; 76 | GAP->conf->lagrAss->alpha = jLagrAss["alpha"]; 77 | GAP->conf->lagrAss->alphastep = jLagrAss["alphastep"]; 78 | GAP->conf->lagrAss->minalpha = jLagrAss["minalpha"]; 79 | GAP->conf->lagrAss->innerIter = jLagrAss["innerIter"]; 80 | GAP->conf->lagrAss->maxiter = jLagrAss["maxiter"]; 81 | 82 | json::Object jlagrCap = JSV["lagrCap"]; 83 | GAP->conf->lagrCap->alpha = jlagrCap["alpha"]; 84 | GAP->conf->lagrCap->alphastep = jlagrCap["alphastep"]; 85 | GAP->conf->lagrAss->minalpha = jLagrAss["minalpha"]; 86 | GAP->conf->lagrCap->innerIter = jlagrCap["innerIter"]; 87 | GAP->conf->lagrCap->maxiter = jlagrCap["maxiter"]; 88 | 89 | json::Object jRINS = JSV["RINS"]; 90 | GAP->conf->rinsConf->maxnodes = jRINS["maxnodes"]; 91 | 92 | json::Object jbeam = JSV["beam"]; 93 | GAP->conf->beam->delta = jbeam["delta"]; 94 | GAP->conf->beam->maxnodes = jbeam["maxnodes"]; 95 | 96 | json::Object jFB = JSV["FandB"]; 97 | GAP->conf->fbConf->delta = jFB["delta"]; 98 | GAP->conf->fbConf->maxnodes = jFB["maxnodes"]; 99 | 100 | json::Object jCorridor = JSV["corridor"]; 101 | GAP->conf->corridorConf->delta = jCorridor["delta"]; 102 | GAP->conf->corridorConf->maxiter = jCorridor["maxiter"]; 103 | 104 | json::Object jLocBranch = JSV["locBranching"]; 105 | GAP->conf->locBranching->k = jLocBranch["k"]; 106 | GAP->conf->locBranching->maxiter = jLocBranch["maxiter"]; 107 | 108 | json::Object jBenders = JSV["benders"]; 109 | GAP->conf->bendersConf->maxiter = jBenders["maxiter"]; 110 | 111 | json::Object jVLSN = JSV["VLSN"]; 112 | GAP->conf->verylargeConf->maxiter = jVLSN["maxiter"]; 113 | GAP->conf->verylargeConf->k = jVLSN["k"]; 114 | 115 | GAP->conf->datafile = JSV["datafile"]; 116 | GAP->conf->isVerbose = JSV["isverbose"]; 117 | GAP->conf->aversionf = JSV["aversionf"]; 118 | return GAP->conf; 119 | } 120 | 121 | // reads instance data from json formatted files 122 | int Persistence::readJSONdata(string fileList) 123 | { 124 | string infile,line,path; 125 | size_t i,j,cont; 126 | vector arrFiles; 127 | 128 | infile = fileList; 129 | cout << "Opening " << infile << endl; 130 | size_t found = fileList.find_last_of("/\\"); 131 | path = fileList.substr(0, found); 132 | cout << "Data path: " << path << '\n'; 133 | 134 | try 135 | { 136 | ifstream fList; 137 | fList.open(infile.c_str(), std::ifstream::in); 138 | fList.exceptions(ifstream::eofbit | ifstream::failbit | ifstream::badbit); 139 | string str; 140 | cont=0; 141 | while ( std::getline(fList,str) && str.length()>0) 142 | { arrFiles.push_back(path+"\\"+str) ; 143 | cout << cont <<") " << arrFiles[cont] << endl; 144 | cont++; 145 | } 146 | fList.close(); 147 | } 148 | catch (std::exception const& e) 149 | { cout << "Error: " << e.what() << endl; 150 | return -1; 151 | } 152 | 153 | // here I got the list of filenames correctly 154 | try 155 | { 156 | cout << "Reading " << arrFiles[0] << endl; 157 | ifstream jData; 158 | jData.open (arrFiles[0], std::ifstream::in); 159 | jData.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit ); 160 | getline(jData,line); 161 | //cout << "line:" << line << endl; 162 | jData.close(); 163 | } 164 | catch(std::exception const& e) 165 | { cout << "Error: " << e.what() << endl; 166 | return -1; 167 | } 168 | 169 | json::Value JSV = json::Deserialize(line); 170 | GAP->name = JSV["name"]; 171 | GAP->n = JSV["numcli"]; 172 | GAP->m = JSV["numserv"]; 173 | GAP->cap = (int*) malloc(GAP->m * sizeof(int)); 174 | for(i=0;icap[i] = JSV["cap"][i]; 176 | 177 | GAP->c = (int**) malloc(GAP->m * sizeof(int *)); 178 | for(i=0;ic[i] = (int*) malloc(GAP->n * sizeof(int)); 180 | for(j=0;jc[i][j] = JSV["cost"][i][j]; 182 | } 183 | 184 | GAP->req = (int**) malloc(GAP->m * sizeof(int *)); 185 | for(i=0;ireq[i] = (int*) malloc(GAP->n * sizeof(int)); 187 | for(j=0;jreq[i][j] = JSV["req"][i][j]; 189 | } 190 | 191 | GAP->zub = INT32_MAX; 192 | 193 | cout << "JSON data read" << endl;; 194 | return 1; 195 | } 196 | -------------------------------------------------------------------------------- /Persistence.h: -------------------------------------------------------------------------------- 1 | #ifndef PERSISTENCE_H 2 | #define PERSISTENCE_H 3 | #include // GetModuleFileName 4 | #include // ifstream 5 | #include // stringstream 6 | #include 7 | #include "json.h" 8 | #include "GAP.h" 9 | 10 | class Persistence 11 | { 12 | public: 13 | Persistence(); 14 | ~Persistence(); 15 | Config* loadConfig(); 16 | int readJSONdata(string); 17 | 18 | GeneralizedAssignemnt* GAP; 19 | protected: 20 | private: 21 | }; 22 | 23 | #endif // PERSISTENCE_H 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MatheuristicsGAP 2 | Accompanying code for the text: 3 | Maniezzo, Vittorio, Boschetti, Marco Antonio, Stützle, Thomas 4 | "Matheuristics, algorithms and implementations" 5 | EURO Advanced Tutorials on Operational Research, Springer, 2021 6 | https://www.springer.com/us/book/9783030702762 7 | 8 | The code (currently incomplete) is meant for exemplificatory purpose only. It provides the gist of each approach and possibly roots for developing specialized, efficient codes. 9 | 10 | The code should NOT be used to draw comparative conclusions, objective of its design is to keep it as simple and barebone as possible. 11 | 12 | This project is licensed under the terms of the MIT license. 13 | -------------------------------------------------------------------------------- /Rins.cpp: -------------------------------------------------------------------------------- 1 | #include "Rins.h" 2 | #include "MIPCplex.h" 3 | #include 4 | 5 | Rins::Rins(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 6 | { 7 | //ctor 8 | GAP = GAPinstance; 9 | m = GAP->m; 10 | n = GAP->n; 11 | sol = GAP->sol; 12 | solbest = GAP->solbest; 13 | req = GAP->req; 14 | } 15 | 16 | Rins::~Rins() 17 | { 18 | //dtor 19 | } 20 | 21 | int Rins::dive(int** c, int maxNodes, int z, int* sol, bool fVerbose) 22 | { int i,j,iter,status; 23 | int zubIter; 24 | int* solIter = new int[n]; 25 | bool fChanged; 26 | 27 | int numRows,numCols,numNZrow; 28 | numRows = n+m; // num of constraints 29 | numCols = n*m; // num of variables 30 | numNZrow= n*m; // max num of nonzero values in a row 31 | MIPCplex* CPX = new MIPCplex(numRows,numCols,numNZrow); 32 | CPX->GAP = GAP; 33 | CPX->allocateMIP(true); // verbose output 34 | CPXsetintparam(CPX->env, CPX_PARAM_RINSHEUR, -1); // disable rins in cplex (not needed) 35 | zubIter = z; 36 | for(j=0;jx[i*n+j] << "\t"; 54 | cout << endl; 55 | } 56 | } 57 | 58 | // heuristic variable fixing 59 | zubIter = 0; 60 | for(j=0;j fix 63 | if(CPX->x[i*n+j] > 0.99 && CPX->lb[i*n+j] < 0.99 && solIter[j] == i) 64 | { cout << "[RINS] Set variable " << i*n+j << ": client " << j << " to " << i << endl; 65 | CPX->lb[i*n+j] = 1; 66 | int cnt = 1; 67 | int* indices = new int[cnt]; // which var 68 | indices[0] = i*n+j; 69 | char* lu = new char[cnt]; // lower limit 70 | lu[0] = 'L'; 71 | double * bd = new double[cnt]; // new bound 72 | bd[0] = 1.0; 73 | status = CPXchgbds(CPX->env, CPX->lp, cnt, indices, lu, bd); 74 | free(indices); 75 | free(lu); 76 | free(bd); 77 | fChanged = true; 78 | } 79 | 80 | // linear primal sufficiently 0, not yet fixed, compatible with seed -> fix 81 | if(CPX->x[i*n+j] < 0.01 && CPX->ub[i*n+j] > 0.01 && solIter[j] != i) 82 | { cout << "[RINS] Set variable " << i*n+j << ": client " << j << " to be different from " << i << endl; 83 | CPX->ub[i*n+j] = 0; 84 | int cnt = 1; 85 | int* indices = new int[cnt]; // which var 86 | indices[0] = i*n+j; 87 | char* lu = new char[cnt]; // upper limit 88 | lu[0] = 'U'; 89 | double * bd = new double[cnt]; // new bound 90 | bd[0] = 0.0; 91 | status = CPXchgbds(CPX->env, CPX->lp, cnt, indices, lu, bd); 92 | free(indices); 93 | free(lu); 94 | free(bd); 95 | fChanged = true; 96 | } 97 | //else if(CPX->lb[i*n+j] < 0.99 && 98 | // CPX->x[i*n+j] > (1-GAP->EPS) && 99 | // solIter[j] != i) // this wouldn't be in rins, it helps with infeasibilities 100 | //{ cout << "Changed " << j << " to " << i << endl; 101 | // solIter[j] = i; // update of incumbent solution, if LP says so 102 | // fChanged = true; 103 | // break; 104 | //} 105 | } 106 | 107 | if(solIter[j] >= 0 && zubIter != z) 108 | zubIter += c[solIter[j]][j]; // when completing partial solutions 109 | else 110 | zubIter = z; 111 | } 112 | 113 | // subMIP, go for MIP to try to complete LP solution (node bound maxNode) 114 | cout << "Solving sub-MIP ..." << endl; 115 | CPXsetintparam(CPX->env, CPX_PARAM_NODELIM, maxNodes); 116 | status = CPX->solveMIP(true,false); 117 | if(status==0) 118 | { cout << "SubMIP, z=" << CPX->objval << endl; 119 | if(CPX->objval < zubIter) 120 | { zubIter = (int) floor( CPX->objval + GAP->EPS ); // the integer cost 121 | for(j=0;jx[i*n+j] > 0.99) 124 | solIter[j] = i; 125 | } 126 | } 127 | 128 | if(abs(zubIter - GAP->checkSol(solIter)) > GAP->EPS) 129 | cout << "[solveGAPbyRins] No feasible solution at this try" << endl; 130 | else 131 | { cout << "[Rins] iter "<< iter <<" zubIter "<< zubIter << endl; 132 | for(j=0;jfreeMIP(); 151 | delete(CPX); 152 | delete(solIter); 153 | return zubIter; 154 | } 155 | 156 | -------------------------------------------------------------------------------- /Rins.h: -------------------------------------------------------------------------------- 1 | #ifndef RINS_H 2 | #define RINS_H 3 | #include "GAP.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Rins 10 | { 11 | public: 12 | GeneralizedAssignemnt* GAP; 13 | 14 | Rins(GeneralizedAssignemnt*, int&); 15 | ~Rins(); 16 | int dive(int**,int, int, int*, bool); 17 | 18 | private: 19 | // local mirrors 20 | int m,n; 21 | int *sol,*solbest; 22 | int** req; 23 | int & zub,zlb; 24 | }; 25 | 26 | #endif // RINS_H 27 | -------------------------------------------------------------------------------- /SS.cpp: -------------------------------------------------------------------------------- 1 | #include "SS.h" 2 | #include // for permutations 3 | #include // for vector hashing 4 | 5 | ScatterSearch::ScatterSearch(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 6 | { 7 | //ctor 8 | GAP = GAPinstance; 9 | m = GAP->m; 10 | n = GAP->n; 11 | sol = GAP->sol; 12 | solbest = GAP->solbest; 13 | req = GAP->req; 14 | } 15 | 16 | ScatterSearch::~ScatterSearch() 17 | { 18 | //dtor 19 | } 20 | 21 | /* 22 | CAUTION: algorithm incomplete! Here just the code to generate the example in the text !! 23 | */ 24 | int ScatterSearch::go_scatter(int** c, int maxiter, int numpop, double alpha) 25 | { int z=0,zcheck,zsol,id; 26 | int j,k,k1,k2,idsol,numsol=0; 27 | vector< vector > pop(numpop); 28 | vector> deltaTau; 29 | vector moveProb(m),zpop(numpop); 30 | vector indCost; // for population initialization 31 | 32 | cout << "Scatter search algorithm incomplete !!" << endl; 33 | 34 | // ------------------------ initialization 35 | for(j=0;jzub); 39 | int nind = sizeof(indCost) / sizeof(indCost[0]); 40 | int cont=0; 41 | do { 42 | zsol = CH->constructWithInd(indCost, false); 43 | if(zsol < INT_MAX) 44 | { id = cont%numpop; 45 | pop[id].clear(); 46 | for(j=0;jsol[j]); 48 | printIntArray(&pop[id][0],n); 49 | cout << "cont= " << cont << "(" << id << ") zsol = " << zsol << endl; 50 | cont++; 51 | } 52 | } while (next_permutation(&indCost[0], &indCost[0]+nind) && cont < 2*numpop); 53 | 54 | if(CH != NULL) delete CH; 55 | CH = NULL; 56 | 57 | // ----------------------------------------- solution improvement 58 | LocalSearch* LS = new LocalSearch(GAP, GAP->zub); 59 | for(k=0;ksol[j] = pop[k][j]; 62 | zsol = LS->opt10(GAP->c,true); 63 | for(j=0;jsol[j]; 64 | //zcheck = GAP->checkSol(pop[k]); 65 | cout << "cont= " << cont << " zsol = " << zsol << endl; 66 | } 67 | if (LS != NULL) delete LS; 68 | LS = NULL; 69 | 70 | // ----------------------------------------- subset generatino (parent set edfinition) 71 | // (here, simply randomly select subsets of three different cost solutions) 72 | 73 | tuple parent; // id in the population and cost of each parent 74 | k = rand() % numpop; 75 | cont = 0; 76 | vector> parents; 77 | vector lstdiff; 78 | int idsol2,zsol2,zson; 79 | 80 | // all pairs of different parents 81 | for(k1 = 0;k1 3) continue; 94 | parent = make_tuple(idsol,zsol); 95 | parents.push_back(parent); 96 | parent = make_tuple(idsol2,zsol2); 97 | parents.push_back(parent); 98 | 99 | //int myints[] = {0,0,1,1,2,2,2,0}; 100 | //pop[idsol].assign (myints,myints+8); // assigning from array. 101 | //int myints2[] = {0,0,2,1,1,2,0,2}; 102 | //zsol = GAP->checkSol(pop[idsol]); 103 | //zsol2 = GAP->checkSol(pop[idsol2]); 104 | //pop[idsol2].assign (myints2,myints2+8); // assigning from array. 105 | zson = pathSon(pop[idsol],pop[idsol2]); 106 | cout << idsol << "-" << idsol2 << " Numdiff= " << lstdiff.size(); 107 | cout << " z1=" << zsol << " z2=" << zsol2 << " zson=" << zson; 108 | cout << (zson != zsol && zsol2 != zson ? "*************" : "<>") << endl; 109 | } 110 | } 111 | 112 | zcheck = 0; 113 | zcheck = GAP->checkSol(solbest); 114 | if (abs(zcheck - zub) > GAP->EPS) 115 | { cout << "[SS] Detected inconsistency" << endl; 116 | z = INT_MAX; 117 | } 118 | else 119 | cout << "zcheck " << zcheck << endl; 120 | cout << "SS zub= " << zub << endl; 121 | 122 | cout << "Scatter search algorithm incomplete !!" << endl; 123 | return zub; 124 | } 125 | 126 | // recombines two parents 127 | int ScatterSearch::pathSon(vector s1, vector s2) 128 | { int res,i,j, cnt=0; 129 | double lb; 130 | 131 | // Lower bound computation, linear bound 132 | int numRows, numCols, numNZrow, statusMIP; 133 | 134 | numRows = n + m; // num of constraints 135 | numCols = n * m; // num of variables 136 | numNZrow = n * m; // max num of nonzero values in a row 137 | MIPCplex* CPX = new MIPCplex(numRows, numCols, numNZrow); 138 | CPX->GAP = GAP; 139 | CPX->allocateMIP(false); // verbose output 140 | statusMIP = CPXsetintparam(CPX->env, CPXPARAM_ScreenOutput, CPX_OFF); 141 | 142 | cnt = n - listDiff(s1,s2).size(); // number of equal assignments 143 | vector indices(cnt); 144 | vector lu(cnt); 145 | vector bd(cnt); 146 | 147 | cnt=0; 148 | for (j = 0; j < n; j++) // common attributes 149 | if(s1[j]==s2[j]) 150 | { indices[cnt] = s1[j] * n + j; 151 | lu[cnt] = 'B'; 152 | bd[cnt] = 1.0; 153 | cnt++; 154 | } 155 | 156 | statusMIP = CPXchgbds(CPX->env, CPX->lp, cnt, &indices[0], &lu[0], &bd[0]); 157 | statusMIP = CPX->solveMIP(true, true); // LP of free instance 158 | if (statusMIP == 0) 159 | { lb = CPX->objval; 160 | cout << "Linear bound: " << lb << endl; 161 | } 162 | else 163 | lb = INT_MAX-1; 164 | 165 | if(CPX != NULL) delete CPX; 166 | res = (int)lb+0.99; 167 | return res; 168 | } 169 | 170 | // list of different assignments in two solutions 171 | vector ScatterSearch::listDiff(vector s1, vector s2) 172 | { int j,num; 173 | vector lstdiff; 174 | 175 | num = 0; 176 | for(j=0;j& v) 186 | { double sum=0; 187 | unsigned int i; 188 | 189 | for(i=0;i= f) break; 198 | } 199 | return i; 200 | } 201 | 202 | 203 | -------------------------------------------------------------------------------- /SS.h: -------------------------------------------------------------------------------- 1 | #ifndef SS_H 2 | #define SS_H 3 | #include "GAP.h" 4 | #include "MIPCplex.h" 5 | #include "ConstructHeu.h" 6 | #include "LocalSearch.h" 7 | #include 8 | 9 | class ScatterSearch 10 | { 11 | public: 12 | GeneralizedAssignemnt* GAP; 13 | 14 | ScatterSearch(GeneralizedAssignemnt*, int&); 15 | ~ScatterSearch(); 16 | int go_scatter(int**, int maxiter, int numpop, double alpha); 17 | 18 | private: 19 | // local mirrors 20 | int m,n; 21 | int *sol,*solbest; 22 | int** req; 23 | int & zub,zlb; 24 | 25 | vector> tau,eta; 26 | 27 | // private functions 28 | int montecarlo(vector& v); 29 | vector listDiff(vector s1, vector s2); 30 | int pathSon(vector s1, vector s2); 31 | }; 32 | 33 | #endif // SS_H 34 | -------------------------------------------------------------------------------- /SimAnnealing.cpp: -------------------------------------------------------------------------------- 1 | #include "SimAnnealing.h" 2 | 3 | SimAnnealing::SimAnnealing(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | SimAnnealing::~SimAnnealing() 15 | { 16 | //dtor 17 | } 18 | 19 | /* 20 | 1. Generate an initial feasible solution S, 21 | initialize S* = S and temperature parameter T. 22 | 2. Generate S’\in N(S). 23 | 3. If z(S') < z(S) then S=S', if (z(S*) > z(S)) S* = S 24 | else accept to set S=S' with probability p = e-(z(S')-z(S))/kT. 25 | 4. If (annealing condition) decrease T. 26 | 5. If not(end condition) go to step 2. 27 | */ 28 | 29 | // This assumes to have in sol a solution to improve 30 | int SimAnnealing::simAnnealing(int** c, double k, double maxT, double alpha, int maxiter, int iterAnneal, double coefAnneal, int fGoMath) 31 | { int z=0; 32 | int i,isol,j,i1,j1,iter,rand,lastimpr; 33 | vector capleft(m); 34 | double T,p; 35 | 36 | // no solution to improve 37 | if(zub==INT_MAX) 38 | { cout << "Uninitialized solution" << endl; 39 | zub = INT_MAX; 40 | goto lend; 41 | } 42 | 43 | if(fGoMath) 44 | { zub = mathSimAnnealing(c, k, maxT, alpha, maxiter, iterAnneal, coefAnneal); 45 | goto lend; 46 | } 47 | 48 | for(i=0;icap[i]; 49 | for (j = 0; j < n; j++) 50 | { capleft[sol[j]] -= req[sol[j]][j]; 51 | z += c[sol[j]][j]; 52 | } 53 | 54 | z = zub; 55 | T = maxT; 56 | iter = 0; 57 | lastimpr = 0; 58 | cout << "Starting Simulated Annealing, zub " << zub << endl; 59 | 60 | start: 61 | iter++; 62 | cout << setw(15); 63 | if(iter%1000 == 0) 64 | cout << "Iter "<= req[i][j]) 74 | { // remove from isol and assign to i 75 | sol[j] = i; 76 | capleft[i] -= req[i][j]; 77 | capleft[isol] += req[isol][j]; 78 | z -= (c[isol][j] - c[i][j]); 79 | if(z= req[i][j]) 86 | { //p = e-(z(S')-z(S))/kT 87 | p = exp(-(c[i][j] - c[isol][j])/(k*T)); 88 | rand = std::rand() % 100; 89 | if(rand0.005 || (iter-lastimpr)<(maxiter/10)) // restart condition 102 | goto start; 103 | else if(iter < maxiter) // restart 104 | { T=maxT; 105 | for(i=0;i= req[i1][j1]) 109 | { sol[j1] = i1; 110 | capleft[i1] -= req[i1][j1]; 111 | capleft[isol] += req[i1][j1]; 112 | z -= (c[isol][j1]-c[i1][j1]); 113 | } 114 | } 115 | goto start; 116 | } 117 | else // terminate 118 | { //Loc2opt(); 119 | cout << "Simulated annealing: ending." << endl; 120 | } 121 | 122 | double zcheck = 0; 123 | zcheck = GAP->checkSol(sol); 124 | if (abs(zcheck - z) > GAP->EPS) 125 | { cout << "[SA] Detected inconsistency" << endl; 126 | z = INT_MAX; 127 | } 128 | 129 | lend: 130 | cout << "SA zub= " << zub << endl; 131 | return zub; 132 | } 133 | 134 | // This assumes to have in sol a solution to improve. implements multiplier djustment 135 | int SimAnnealing::mathSimAnnealing(int** c, double k, double maxT, double alpha, int maxiter, int iterAnneal, double coefAnneal) 136 | { 137 | int z = 0; 138 | int i, isol, j, i1, j1, iter, rand, lastimpr, nInfeas; 139 | vector capleft(m); 140 | double T, p, zcheck; 141 | 142 | vector> cPrime(m, vector(n)); // cPrime costs wil be adjusted 143 | 144 | for (i = 0; icap[i]; 145 | for (j = 0; j < n; j++) 146 | { capleft[sol[j]] -= req[sol[j]][j]; 147 | for (i = 0; ic[sol[j]][j]; 203 | 204 | zcheck = 0; 205 | zcheck = GAP->checkSol(sol); 206 | if (abs(zcheck - z) > GAP->EPS) 207 | { cout << "[MSA] Detected inconsistency" << endl; 208 | z = INT_MAX; 209 | } 210 | else 211 | cout << "iter " << iter << " feasible! z="<< z << endl; 212 | 213 | if (z0.005 || (iter - lastimpr)<(maxiter / 10)) // restart condition 224 | goto start; 225 | else if (iter < maxiter) // restart 226 | { 227 | T = maxT; 228 | for (i = 0; i= req[i1][j1]) 233 | { sol[j1] = i1; 234 | capleft[i1] -= req[i1][j1]; 235 | capleft[isol] += req[i1][j1]; 236 | z -= (cPrime[isol][j1] - cPrime[i1][j1]); 237 | } 238 | } 239 | goto start; 240 | } 241 | else // terminate 242 | { //Loc2opt(); 243 | cout << "Matheuristic simulated annealing: ending." << endl; 244 | } 245 | return zub; 246 | } -------------------------------------------------------------------------------- /SimAnnealing.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMANNEALING_H 2 | #define SIMANNEALING_H 3 | #include "GAP.h" 4 | 5 | class SimAnnealing 6 | { 7 | public: 8 | GeneralizedAssignemnt* GAP; 9 | 10 | SimAnnealing(GeneralizedAssignemnt*, int&); 11 | ~SimAnnealing(); 12 | int simAnnealing(int**, double, double, double, int, int, double, int); 13 | int mathSimAnnealing(int**, double, double, double, int, int, double); 14 | 15 | private: 16 | // local mirrors 17 | int m,n; 18 | int *sol,*solbest; 19 | int** req; 20 | int & zub,zlb; 21 | }; 22 | 23 | #endif // SIMANNEALING_H 24 | -------------------------------------------------------------------------------- /TabuSearch.cpp: -------------------------------------------------------------------------------- 1 | #include "TabuSearch.h" 2 | 3 | TabuSearch::TabuSearch(GeneralizedAssignemnt* GAPinstance, int & zz) : zub(zz) 4 | { 5 | //ctor 6 | GAP = GAPinstance; 7 | m = GAP->m; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | TabuSearch::~TabuSearch() 15 | { 16 | //dtor 17 | } 18 | 19 | /* 20 | 1. Generate an initial feasible solution S, 21 | set S* = S and initialize TL=nil. 22 | 2. Find S' \in N(S), such that 23 | z(S')=min {z(S^), foreach S^\in N(S), S^\notin TL}. 24 | 3. S=S', TL=TL \in {S}, if (z(S*) > z(S)) set S* = S. 25 | 4. If not(end condition) go to step 2. 26 | */ 27 | // This is based on opt11 28 | int TabuSearch::tabuSearch(int** c, int Ttenure, int maxiter, int fGoMath) 29 | { int z=0,delta,DeltaMax,cap1,cap2; 30 | int i,j,i1,i2,j1,j2, i1max, j1max, i2max, j2max,iter; 31 | vector capleft(m); 32 | vector> TL(m, vector(n,0)); // m*n 2d vector initialized with 0 33 | double zcheck; 34 | 35 | // no solution to improve 36 | if(zub==INT_MAX) 37 | { cout << "Uninitialized solution" << endl; 38 | return INT_MAX; 39 | } 40 | Rins* RINS = new Rins(GAP, GAP->zub); // in case of matheuristic 41 | 42 | for(i=0;icap[i]; 43 | for (j = 0; j < n; j++) 44 | { capleft[sol[j]] -= req[sol[j]][j]; 45 | z += c[sol[j]][j]; 46 | } 47 | 48 | iter = 0; 49 | Ttenure = Ttenure*m; // very heuristic guess 50 | cout << "Starting tabu search" << endl; 51 | 52 | start: 53 | DeltaMax = i1max = j1max = i2max = j2max =INT_MIN; 54 | 55 | iter++; 56 | for (j1 = 0; j1 DeltaMax && TL[i1][j1]= 0 && cap2 >= 0) 67 | { 68 | DeltaMax = delta; 69 | j1max = j1; 70 | j2max = j2; 71 | i1max = i1; 72 | i2max = i2; 73 | } 74 | } 75 | } 76 | 77 | if(i1max == INT_MIN || j1max == INT_MIN || i2max == INT_MIN || j2max == INT_MIN) 78 | { cout << "No feasible neighbor found, exiting" << endl; 79 | goto lend; 80 | } 81 | 82 | // new incumbent solution 83 | capleft[i1max] += req[i1max][j1max] - req[i1max][j2max]; 84 | capleft[i2max] += req[i2max][j2max] - req[i2max][j1max]; 85 | sol[j1max] = i2max; 86 | sol[j2max] = i1max; 87 | z -= DeltaMax; 88 | TL[i1max][j2max] = iter + Ttenure; 89 | TL[i2max][j1max] = iter + Ttenure; 90 | 91 | if(z < zub) // improved solbest 92 | { zcheck = 0; 93 | zcheck = GAP->checkSol(sol); 94 | if (abs(zcheck - z) > GAP->EPS) 95 | { cout << "[TS] Solution structure inconsistency" << endl; 96 | z = INT_MAX; 97 | goto lend; 98 | } 99 | for(i=0;im; 8 | n = GAP->n; 9 | sol = GAP->sol; 10 | solbest = GAP->solbest; 11 | req = GAP->req; 12 | } 13 | 14 | VeryLarge::~VeryLarge() 15 | { 16 | //dtor 17 | } 18 | 19 | int VeryLarge::verylarge(int** c, int k, int maxiter, bool fVerbose) 20 | { 21 | int i, j, iter, status; 22 | int zubIter; 23 | int* solIter = new int[n]; 24 | 25 | if (GAP->n == NULL) 26 | { 27 | cout << "Instance undefined. Exiting" << endl; 28 | return INT_MAX; 29 | } 30 | 31 | int numRows, numCols, numNZrow; 32 | numRows = n + m; // num of constraints 33 | numCols = n * m; // num of variables 34 | numNZrow = n * m; // max num of nonzero values in a row 35 | MIPCplex* CPX = new MIPCplex(numRows, numCols, numNZrow); 36 | CPX->GAP = GAP; 37 | CPX->allocateMIP(fVerbose); 38 | zubIter = GAP->checkSol(sol); 39 | for (j = 0; jx[i*n + j] << " "; 60 | cout << endl; 61 | } 62 | } 63 | // reads the solution 64 | zubIter = 0; 65 | for (j = 0; jx[i*n + j] > 0.5) 69 | { 70 | solIter[j] = i; 71 | break; 72 | } 73 | zubIter += c[solIter[j]][j]; 74 | } 75 | 76 | if (abs(zubIter - GAP->checkSol(solIter)) > GAP->EPS) 77 | cout << "[verylarge] No feasible solution at this iteration" << endl; 78 | else 79 | { 80 | if(fVerbose) 81 | { cout << "[VLSN] iter " << iter << " zubIter " << zubIter << endl; 82 | cout << "Solution: "; for (j = 0; jfreeMIP(); 103 | delete(CPX); 104 | delete(solIter); 105 | return zub; 106 | } 107 | 108 | // this frees the variables in the ejection set 109 | void VeryLarge::fixVariables(int** c, MIPCplex* CPX, int* solIter, int k) 110 | { 111 | int i, j, isol, status, numfix, temp; 112 | bool isInSet; 113 | double minr; 114 | vector lstClients; 115 | vector lstSet; 116 | vector indRatios(n); 117 | vector ratios; // to be used for client ordering 118 | auto compRatios = [&ratios](int a, int b) { return ratios[a] < ratios[b]; }; // ASC order 119 | 120 | for (j = 0; jlb[i*n + j] == 0.0) // lb OK, only ub could be wrong 174 | { 175 | CPX->ub[i*n + j] = 1.0; 176 | bd[i*n + j] = 1.0; 177 | lu[i*n + j] = 'U'; // bd[j] is an upper bound 178 | } 179 | else // lb wrong, ub should be OK 180 | { 181 | CPX->lb[i*n + j] = 0.0; 182 | bd[i*n + j] = 0.0; 183 | lu[i*n + j] = 'L'; // bd[j] is an upper bound 184 | } 185 | } 186 | else // not in set 187 | { 188 | isol = solIter[j]; 189 | if (i == isol) 190 | { 191 | CPX->lb[i*n + j] = 1.0; // fixing in the solution 192 | bd[i*n + j] = 1.0; 193 | } 194 | else 195 | { 196 | CPX->lb[i*n + j] = 0.0; // forbidding in the solution 197 | bd[i*n + j] = 0.0; 198 | } 199 | lu[i*n + j] = 'B'; // bd[j] is the lower and upper bound 200 | } 201 | indices[i*n + j] = i * n + j; 202 | } 203 | } 204 | cout << endl; 205 | 206 | status = CPXchgbds(CPX->env, CPX->lp, cnt, indices, lu, bd); 207 | free(indices); 208 | free(lu); 209 | free(bd); 210 | 211 | return; 212 | } 213 | -------------------------------------------------------------------------------- /VLSN.h: -------------------------------------------------------------------------------- 1 | #ifndef VLSN_H 2 | #define VLSN_H 3 | #include "GAP.h" 4 | #include "MIPCplex.h" 5 | 6 | 7 | class VeryLarge 8 | { 9 | public: 10 | GeneralizedAssignemnt* GAP; 11 | 12 | VeryLarge(GeneralizedAssignemnt*, int&); 13 | ~VeryLarge(); 14 | int verylarge(int** c, int delta, int maxiter, bool fVerbose); 15 | 16 | private: 17 | // local mirrors 18 | int m,n; 19 | int *sol,*solbest; 20 | int** req; 21 | int & zub,zlb; 22 | 23 | void fixVariables(int** c, MIPCplex* CPX, int* solIter, int k); 24 | }; 25 | 26 | #endif // VLSN_H 27 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Config 8 | { 9 | public: 10 | class SimAnn 11 | { public: 12 | double maxT; 13 | double k; 14 | int maxiter; 15 | }; 16 | 17 | class Tabu 18 | { public int Ttenure; 19 | public int maxiter; 20 | } 21 | 22 | class LagrAss 23 | { 24 | public: 25 | double alpha; 26 | double alphastep; 27 | int maxiter; 28 | int innerIter; 29 | } 30 | 31 | class LagrCap 32 | { 33 | public: 34 | double alpha; 35 | double alphastep; 36 | int maxiter; 37 | int innerIter; 38 | } 39 | 40 | class Corridor 41 | { public: 42 | int delta; 43 | int maxiter; 44 | } 45 | 46 | class LocBranching 47 | { public: 48 | int k; 49 | int maxiter; 50 | } 51 | 52 | SimAnn* SA; 53 | Tabu* TS; 54 | LagrAss* lagrAss; 55 | LagrCap* lagrCap; 56 | Corridor* corridor; 57 | LocBranching* locBranching; 58 | string datafile; 59 | int isverbose; 60 | } 61 | 62 | #endif // CONFIG_H 63 | -------------------------------------------------------------------------------- /fileList.txt: -------------------------------------------------------------------------------- 1 | homemade\example8x3.json 2 | 3 | yagiura\gapd\gapd_5.json 4 | ..\..\..\..\Ongoing\parameters\Generation\Generation\bin\instances\gamma_100_5_0.json 5 | 6 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Controller.h" 3 | 4 | int main(int argc, char* argv[]) 5 | { int input=-1; 6 | clock_t start, end; 7 | Controller* C = new Controller(); 8 | 9 | do{ 10 | if(argc == 2 && input == -1) 11 | { input=atoi(argv[1]); 12 | goto lstart; 13 | } 14 | 15 | cout << "\n\nMatHeuristics, select:" << endl; 16 | cout << "1) Lower bounds" << endl; 17 | cout << "2) Exact" << endl; 18 | cout << " ----------------------------------- 1: simple heuristics" << endl; 19 | cout << " 3) Simple constructive" << endl; 20 | cout << " 4) MTHG" << endl; 21 | cout << (C->GAP->zub == INT_MAX ? " X" : " 5") << ") opt01" << endl; 22 | cout << " ----------------------------------- 2: metaheuristics" << endl; 23 | cout << (C->GAP->zub == INT_MAX ? " X" : " 6") << ") Simulated Annealing" << endl; 24 | cout << (C->GAP->zub == INT_MAX ? " X" : " 7") << ") Tabu Search" << endl; 25 | cout << (C->GAP->zub == INT_MAX ? " X" : " 8") << ") Iterated Local Search (with data perturbation)" << endl; 26 | cout << (C->GAP->zub == INT_MAX ? " X" : " 9") << ") GRASP" << endl; 27 | cout << (C->GAP->zub == INT_MAX ? " X" : "10") << ") VNS" << endl; 28 | cout << "11) Ejection chains" << endl; 29 | cout << "12) Genetic algorithm" << endl; 30 | cout << "13) Ant Colony Optimization" << endl; 31 | cout << "14) Scatter search" << endl; 32 | cout << " ----------------------------------- 3: MH uniques" << endl; 33 | cout << "15) Lagrangian, relax capacities" << endl; 34 | cout << "16) Lagrangian, relax assignments" << endl; 35 | cout << (C->GAP->zub == INT_MAX ? "X" : "17") << ") Rins" << endl; 36 | cout << "18) Beam search" << endl; 37 | cout << "19) Fore and back" << endl; 38 | cout << (C->GAP->zub == INT_MAX ? "X" : "20") << ") Corridor" << endl; 39 | cout << (C->GAP->zub == INT_MAX ? "X" : "21") << ") Local Branching" << endl; 40 | cout << (C->GAP->zub == INT_MAX ? "X" : "22") << ") Benders" << endl; 41 | cout << "23) Kernel search" << endl; 42 | cout << (C->GAP->zub == INT_MAX ? "X" : "24") << ") Very large-scale neigh search" << endl; 43 | cout << endl; 44 | cout << "0) Exit" << endl; 45 | cout << "\n->"; 46 | 47 | cin >> input; 48 | 49 | lstart: 50 | start = clock(); 51 | switch (input) 52 | { 53 | case (1): 54 | cout << "Lower bounds" << endl; 55 | C->computeBounds(); 56 | break; 57 | case (2): 58 | cout << "Exact (cplex)" << endl; 59 | C->exactCplex(); 60 | break; 61 | case (3): 62 | cout << "Simple constructive" << endl; 63 | C->simpleConstruct(); 64 | break; 65 | case (4): 66 | cout << "MTHG" << endl; 67 | C->run_mthg(); 68 | break; 69 | case (5): 70 | cout << "opt01" << endl; 71 | C->opt10(); 72 | break; 73 | case (6): 74 | cout << "Simulated Annealing" << endl; 75 | C->run_simAnn(); 76 | break; 77 | case (7): 78 | cout << "Tabu Search" << endl; 79 | C->run_tabuSearch(); 80 | break; 81 | case (8): 82 | cout << "Iterated Local Search" << endl; 83 | C->run_iteratedLS(); 84 | break; 85 | case (9): 86 | cout << "GRASP" << endl; 87 | C->run_GRASP(); 88 | break; 89 | case (10): 90 | cout << "VNS" << endl; 91 | C->run_VNS(); 92 | break; 93 | case (11): 94 | cout << "Ejection chain" << endl; 95 | C->run_ejection(); 96 | break; 97 | case (12): 98 | cout << "Genetic algorithm" << endl; 99 | C->run_genAlgo(); 100 | break; 101 | case (13): 102 | cout << "Ant Colony Optiization" << endl; 103 | C->run_ACO(); 104 | break; 105 | case (14): 106 | cout << "Scatter search" << endl; 107 | C->run_SS(); 108 | break; 109 | case (15): 110 | cout << "Lagrangian, relax assignments" << endl; 111 | C->run_lagrAss(); 112 | break; 113 | case (16): 114 | cout << "Lagrangian, relax capacities" << endl; 115 | C->run_lagrCap(); 116 | break; 117 | case (17): 118 | cout << "Rins" << endl; 119 | C->run_rins(); 120 | break; 121 | case (18): 122 | cout << "Beam search" << endl; 123 | C->run_beam(); 124 | break; 125 | case (19): 126 | cout << "Forward & Backward" << endl; 127 | C->run_FandB(); 128 | break; 129 | case (20): 130 | cout << "Corridor" << endl; 131 | C->run_Corridor(); 132 | break; 133 | case (21): 134 | cout << "Local branching" << endl; 135 | C->run_localBranching(); 136 | break; 137 | case (22): 138 | cout << "Benders" << endl; 139 | C->run_benders(); 140 | break; 141 | case (23): 142 | cout << "Kernel" << endl; 143 | C->run_kernel(); 144 | break; 145 | case (24): 146 | cout << "VLSN" << endl; 147 | C->run_VLSN(); 148 | break; 149 | case (0): 150 | goto lend; 151 | break; 152 | default: 153 | cout << "Error in input choice" << endl; 154 | input = 666; 155 | break; 156 | } 157 | end = clock(); 158 | cout << "Time: " << (double)(end - start)/CLOCKS_PER_SEC << endl; 159 | if(argc==2) {delete C; return 0;} 160 | } while(true); 161 | 162 | lend: 163 | delete C; 164 | cout << "\n to exit ..."; cin.get(); 165 | return 0; 166 | } 167 | --------------------------------------------------------------------------------