diff --git a/ColumnGeneration/base.cpp b/ColumnGeneration/base.cpp index 0ea60116e31c71a039b66f8dcf053431fbee7f5e..2bce7dba61cda1ee6f937d9c820ada4542232a65 100644 --- a/ColumnGeneration/base.cpp +++ b/ColumnGeneration/base.cpp @@ -2881,8 +2881,8 @@ void c_RMP::SetConstraintSense(int contraintIndex, char sense) { char _sense[] = { sense }; int _indices[] = { contraintIndex }; - //CPXchgsense(ctlr->CPLEXEnv()->getEnv(), (CPXLPptr)this, 1, _indices, _sense); - chgsense(1, _indices, _sense); + CPXchgsense(ctlr->CPLEXEnv()->getEnv(), (CPXLPptr)this, 1, _indices, _sense); + //chgsense(1, _indices, _sense); //XXX CT } diff --git a/SharedFiles/timeinfo.h b/SharedFiles/timeinfo.h deleted file mode 100644 index 676cd69adf95c05a5a19bf7a09f59ce17b160d23..0000000000000000000000000000000000000000 --- a/SharedFiles/timeinfo.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef TIMEINFO_H -#define TIMEINFO_H - -#include <iostream> -#include <sstream> -#include <iomanip> - -#include <time.h> -#include <math.h> - -class c_TimeInfo { - clock_t start; - clock_t stop; - double offset; - int i_num_stops; - double d_min_time; - double d_max_time; -public: - c_TimeInfo() - : start( clock() ), offset(0), i_num_stops(0), d_min_time( 10e30), d_max_time(0.0) { stop = start; } - - void Start() { start = clock(); offset=0; i_num_stops=0; stop=0; } // stop == 0 indicates that timer is running - void Restart() { offset += stop-start; start=clock(); stop=0; } - void Stop() { stop=clock(); - i_num_stops++; - if ( stop-start < d_min_time ) d_min_time = stop-start; - if ( stop-start > d_max_time ) d_max_time = stop-start; - } - void Reset() { offset=0; i_num_stops=0; start = clock(); stop = start; d_min_time=10e30; d_max_time=0; } - - int NumStops() const { return i_num_stops; } - // the following methods work in both situations: timer is still running or timer is stopped - double Hours() const { return double( (stop==0?clock():stop) - start + offset ) / ( CLOCKS_PER_SEC * 3600.0 ); } - double Minutes() const { return double( (stop==0?clock():stop) - start + offset ) / ( CLOCKS_PER_SEC * 60.0 ); } - double Seconds() const { return double( (stop==0?clock():stop) - start + offset ) / CLOCKS_PER_SEC; } - double MilliSeconds() const { return double( (stop==0?clock():stop) - start + offset ) / ( CLOCKS_PER_SEC / 1000.0 ); } - // avg, min, max taken over all times that are stopped; the timer might be running at the moment, but this last run is not considered - double AvgHours() const { return double( stop - start + offset ) / ( CLOCKS_PER_SEC * 3600.0 ) / double(i_num_stops); } - double AvgMinutes() const { return double( stop - start + offset ) / ( CLOCKS_PER_SEC * 60.0 )/ double(i_num_stops); } - double AvgSeconds() const { return double( stop - start + offset ) / CLOCKS_PER_SEC / double(i_num_stops); } - double AvgMilliSeconds() const { return double( stop - start + offset ) / ( CLOCKS_PER_SEC / 1000.0 )/ double(i_num_stops); } - double MinHours() const { return double( d_min_time ) / ( CLOCKS_PER_SEC * 3600.0 ); } - double MinMinutes() const { return double( d_min_time ) / ( CLOCKS_PER_SEC * 60.0 ); } - double MinSeconds() const { return double( d_min_time ) / CLOCKS_PER_SEC; } - double MinMilliSeconds() const { return double( d_min_time ) / ( CLOCKS_PER_SEC / 1000.0 ); } - double MaxHours() const { return double( d_max_time ) / ( CLOCKS_PER_SEC * 3600.0 ); } - double MaxMinutes() const { return double( d_max_time ) / ( CLOCKS_PER_SEC * 60.0 ); } - double MaxSeconds() const { return double( d_max_time ) / CLOCKS_PER_SEC; } - double MaxMilliSeconds() const { return double( d_max_time ) / ( CLOCKS_PER_SEC / 1000.0 ); } - - std::string FormattedTime() const { - int hours = (int) floor( Hours() ); - int mins = (int) floor( Minutes() ) - 60 * (int) floor( Hours() ); - int secs = (int) floor( Seconds() ) - 60 * (int) floor( Minutes() ); - int ms = (int) floor( MilliSeconds() ) - 1000 * (int) floor( Seconds() ); - using namespace std; - ostringstream buffer; - buffer << setfill('0') << setw(2) << hours << ":"; - buffer << setfill('0') << setw(2) << mins << ":"; - buffer << setfill('0') << setw(2) << secs << ","; - buffer << setfill('0') << setw(3) << ms; - return buffer.str(); - } - std::string FormattedAvgTime() const { - int hours = (int) floor( AvgHours() ); - int mins = (int) floor( AvgMinutes() ) - 60 * (int) floor( AvgHours() ); - int secs = (int) floor( AvgSeconds() ) - 60 * (int) floor( AvgMinutes() ); - int ms = (int) floor( AvgMilliSeconds() ) - 1000 * (int) floor( AvgSeconds() ); - using namespace std; - ostringstream buffer; - buffer << setfill('0') << setw(2) << hours << ":"; - buffer << setfill('0') << setw(2) << mins << ":"; - buffer << setfill('0') << setw(2) << secs << ","; - buffer << setfill('0') << setw(3) << ms; - return buffer.str(); - } - std::string FormattedMinTime() const { - int hours = (int) floor( MinHours() ); - int mins = (int) floor( MinMinutes() ) - 60 * (int) floor( MinHours() ); - int secs = (int) floor( MinSeconds() ) - 60 * (int) floor( MinMinutes() ); - int ms = (int) floor( MinMilliSeconds() ) - 1000 * (int) floor( MinSeconds() ); - using namespace std; - ostringstream buffer; - buffer << setfill('0') << setw(2) << hours << ":"; - buffer << setfill('0') << setw(2) << mins << ":"; - buffer << setfill('0') << setw(2) << secs << ","; - buffer << setfill('0') << setw(3) << ms; - return buffer.str(); - } - std::string FormattedMaxTime() const { - int hours = (int) floor( MaxHours() ); - int mins = (int) floor( MaxMinutes() ) - 60 * (int) floor( MaxHours() ); - int secs = (int) floor( MaxSeconds() ) - 60 * (int) floor( MaxMinutes() ); - int ms = (int) floor( MaxMilliSeconds() ) - 1000 * (int) floor( MaxSeconds() ); - using namespace std; - ostringstream buffer; - buffer << setfill('0') << setw(2) << hours << ":"; - buffer << setfill('0') << setw(2) << mins << ":"; - buffer << setfill('0') << setw(2) << secs << ","; - buffer << setfill('0') << setw(3) << ms; - return buffer.str(); - } -}; - -#endif diff --git a/bcp_cvrptw.cpp b/bcp_cvrptw.cpp index 9eaca8ae38a1795449fb1f0dc03d7f04c28df756..c829ad9e0a86bf899b84ae73d3772db8ff272f0d 100644 --- a/bcp_cvrptw.cpp +++ b/bcp_cvrptw.cpp @@ -59,7 +59,11 @@ c_ControllerCVRPTW::c_ControllerCVRPTW(std::string instanceFile, string schedule BranchingTieBreakerRule("BranchingTieBreakerRule", 1, false), cnt_extendedFWLabels(0), cnt_extendedBWLabels(0), - i_numAddedColumns(0) + i_numAddedColumns(0), + PricingHierarchyStandardOrder("PricingHierarchyStandardOrder",true,true), + i_startHierarchyId(0), + MaxNumSubsetRow("MaxNumSubsetRow",300,true), + BranchVehicleFirst("BranchVehicleFirst",true,true) { // Parameters AddParameter( &BranchVal ); @@ -93,6 +97,9 @@ c_ControllerCVRPTW::c_ControllerCVRPTW(std::string instanceFile, string schedule AddParameter( &BranchingCustomerDayCandidates ); AddParameter( &RestrictVerticesWithDominanceCheck ); AddParameter( &BranchingTieBreakerRule ); + AddParameter(& PricingHierarchyStandardOrder); + AddParameter(&MaxNumSubsetRow); + AddParameter(&BranchVehicleFirst); } @@ -108,6 +115,12 @@ c_ControllerCVRPTW::~c_ControllerCVRPTW() void c_ControllerCVRPTW::Go( void ) { + + if (MaxNumSubsetRow() > 300) + { + cout << "Maximum number of SR cuts is " << 300 << " atm, if you want more change it in cvrptw_ref.h!" << endl; + MaxNumSubsetRow.SetValue(300); + } taskNetwork = NetworkOfTasks(); schedulePartNetwork = NetworkOfScheduleParts(); @@ -185,7 +198,7 @@ void c_ControllerCVRPTW::WriteSolutionInFile( string FileName ) c_IntegerField minColsPerPricer( 580, "minColsPerPricer|Settings", this->PricingHierarchyMinNumColsToGenerate()); c_IntegerField maxFailuresPerPricer( 590, "maxFailuresPerPricer|Settings", this->PricingHierarchyMaxNumFailuresBeforeSwitchOff()); - //c_BoolField hierarchyOrder( 591, "StandardHierarchyOrder|Settings", this->PricingHierarchyStandardOrder() ); + c_BoolField hierarchyOrder( 591, "StandardHierarchyOrder|Settings", this->PricingHierarchyStandardOrder() ); c_IntegerField solver( 600, "Solver|Settings", this->Solver()); c_IntegerField ngSize( 602, "NgSizeInit|Settings", this->NgNeighborhoodSize()); @@ -385,7 +398,9 @@ void c_ControllerCVRPTW::AddPricingProblems() if( hierarchies[d]->GetNumPricingLevels() > maxNumPricingLevels) maxNumPricingLevels = hierarchies[d]->GetNumPricingLevels(); AddPricingProblemHierarchy( hierarchies[d] ); + v_hierarchy_vec.push_back(hierarchies[d]); } + v_numFailures_hierarchy = vector<int>(maxNumPricingLevels, 0); //setNumEasierPricingProblems(easierPricingProblems); } @@ -404,12 +419,12 @@ void c_ControllerCVRPTW::Pricing(int iteration, c_DualVariables* dual, list<c_Co Info3() << "Pricing " << flush; c_TimeInfo pricing_time_info; + pricing_time_info.Start(); int generated_cols = 0; - vector<c_PricingProblemHierarchy*>& hierarchies = PricingProblemHierarchies(); + if (PricingHierarchyStandardOrder()) { - vector<c_PricingProblemHierarchy*>::iterator hh; - for (hh = hierarchies.begin(); hh != hierarchies.end(); ++hh) + for (auto hh = v_hierarchy_vec.begin(); hh != v_hierarchy_vec.end(); ++hh) { if (TimeOut()) return; @@ -422,10 +437,11 @@ void c_ControllerCVRPTW::Pricing(int iteration, c_DualVariables* dual, list<c_Co else { //NowTODO int startHierarchy = GetStartHierarchy(); - int numHierarchies = (int)hierarchies.size(); - int maxPricingLevel = hierarchies[0]->GetNumPricingLevels() - 1; - for (int h = 0; h < numHierarchies; h++) { - hierarchies[h]->SetBestReducedCost(-10 * INFTY); //Initialize reduced cost to -infinity, so that the lagrangean lower bound is also valid, if not all pricing hierarchies are started + int numHierarchies = (int)v_hierarchy_vec.size(); + int maxPricingLevel = v_hierarchy_vec[0]->GetNumPricingLevels() - 1; + for (auto hh = v_hierarchy_vec.begin(); hh != v_hierarchy_vec.end(); hh++) { + c_PricingSolverHierarchyCVRPTW* hierarchy = (c_PricingSolverHierarchyCVRPTW * ) *hh; + hierarchy->SetBestReducedCost(-10 * INFTY); //Initialize reduced cost to -infinity, so that the lagrangean lower bound is also valid, if not all pricing hierarchies are started } bool continuePricing = true; @@ -434,8 +450,9 @@ void c_ControllerCVRPTW::Pricing(int iteration, c_DualVariables* dual, list<c_Co do { if (TimeOut()) return; - - c_PricingProblemHierarchy* hierarchy = hierarchies[startHierarchy]; + if(InfoLevel() >= 3) + Info3() << "Hierarchy " << startHierarchy << ": "; + c_PricingSolverHierarchyCVRPTW* hierarchy = v_hierarchy_vec[startHierarchy]; hierarchy->Update(dual); if (all_of(v_failed.begin(), v_failed.end(), [](bool b) {return b; })) { @@ -446,11 +463,11 @@ void c_ControllerCVRPTW::Pricing(int iteration, c_DualVariables* dual, list<c_Co //increase pricing level of all hierarchies (at least temporarily; if maxNumFailures is not reached, it is decreased again) int minPricingStartLevel = maxPricingLevel; for (int p = 0; p < numHierarchies; p++) { - if (hierarchies[p]->GetPricingStartLevel() < minPricingStartLevel) - minPricingStartLevel = hierarchies[p]->GetPricingStartLevel(); + if (v_hierarchy_vec[p]->GetPricingStartLevel() < minPricingStartLevel) + minPricingStartLevel = v_hierarchy_vec[p]->GetPricingStartLevel(); } for (int p = 0; p < v_failed.size(); p++) { - hierarchies[p]->SetPricingStartLevel(minPricingStartLevel + 1); //hierarchies[p]->GetPricingStartLevel() +1 ); + v_hierarchy_vec[p]->SetPricingStartLevel(minPricingStartLevel + 1); //hierarchies[p]->GetPricingStartLevel() +1 ); v_failed[p] = false; } } @@ -1678,11 +1695,13 @@ void c_DualVariablesCVRPTW::OutputInOStream( ostream& s ) const s << "Mu(" << d << ")= " << mu(d) << endl; } - if( ctlr->IsAggregated() ){ + if( ctlr->IsAggregated() && ctlr->RegularVisits()) + { for ( int i = 0; i<ctlr->NumNodes(); i++ ) if ( ctlr->IsCustomerNode(i) ) s << "Tau( " << i << ")=" << tau(i) << endl; - } else{ + } else + { for ( int i = 0; i<ctlr->NumNodes(); i++ ) if ( ctlr->IsCustomerNode(i) ) s << "Pi( " << i << ")=" << pi(i) << endl; @@ -3479,7 +3498,7 @@ int c_PricingSolverCVRPTW::Go( c_DualVariables* dual, list<c_ColumnPricePair>& c routes_BIDIR[i].second.second->Help() - routes_BIDIR[i].second.first->Help() ); } c_TourColumnCVRPTW* col = new c_TourColumnCVRPTW( ctlr, tour, cost, i_day, duration ); - if ( ctlr->InfoLevel() >= 3 ) + if ( ctlr->InfoLevel() >= 4 ) ctlr->Info3() << *col << ": " << rdc << endl; cols_and_prices.push_back( c_ColumnPricePair( col, rdc ) ); @@ -3508,7 +3527,6 @@ int c_PricingSolverCVRPTW::Go( c_DualVariables* dual, list<c_ColumnPricePair>& c double rdc2 = col->ReducedCosts( *dual ); if ( abs(rdc - rdc2) > 0.0001 ) - /*if ( abs( (rdc - rdc2) ) > 0.0001 )*/ { cout << "Wrong rdc: col-rdc=" << rdc2 << " vs. pricing-rdc=" << rdc << endl; cout << "Diff: " << rdc2 - rdc << endl; @@ -3626,7 +3644,7 @@ int c_PricingSolverCVRPTW::Go( c_DualVariables* dual, list<c_ColumnPricePair>& c timer.Stop(); - if( ctlr->InfoLevel() >= 2){ + if( ctlr->InfoLevel() >= 4){ cout << setw(8) << timer.MilliSeconds() << "ms: " << (b_exactDom? "Exact" : "Heuristic") << " Pricer with nwSize = " << i_networkSize << " for day " << i_day << " has generated " << ((int) cols_and_prices.size() - numColsBefore) << " column(s)." << endl; } @@ -3959,6 +3977,67 @@ void c_PricingSolverHierarchyCVRPTW::Update(c_DualVariables* dual) } } +int c_PricingSolverHierarchyCVRPTW::Go(c_DualVariables* dual, list<c_ColumnPricePair>& cols_and_prices, int NumPricersUsed) +{ + c_ControllerCVRPTW* ctlr = (c_ControllerCVRPTW*)Controller(); + //NowTODO + int num_generated_cols = 0; + d_best_reduced_costs = -10 * INFTY; + int start_level = min(i_pricing_start_level, (int)v_hierarchy.size() - 1); + for (int pricing_level = start_level; pricing_level < (int)v_hierarchy.size(); pricing_level++) + { + if (ctlr->TimeOut()) + return 0; + + // call pricer + c_PricingProblem* pricer = v_hierarchy[pricing_level]; + pricer->Update(dual); + double value = 0.0; + int cols_before = (int)cols_and_prices.size(); + if (ctlr->InfoLevel() >= 3) + ctlr->Info3() << "[" << pricing_level << "] "; + int pricer_return_val = pricer->Go(dual, cols_and_prices, value); + num_generated_cols += ((int)cols_and_prices.size() - cols_before); + ctlr->Set_number_of_solved_pricing_problems(ctlr->InfoNumberOfSolvedPricingProblems() + 1); + // update d_best_reduced_costs + if (pricing_level == (int)v_hierarchy.size() - 1) + { + d_best_reduced_costs = value; + if (num_generated_cols == 0) + d_best_reduced_costs = 0.0; + } + + // update failures and start level + v_num_failures[pricing_level] = (num_generated_cols < i_min_num_columns) ? v_num_failures[pricing_level] + 1 : v_num_failures[pricing_level]; //else 0 if consecutive failures are counted, otherwise v_num_failures[pricing_level] + + if (!ctlr->PricingHierarchyStandardOrder()) { //pricing_level > p_controller->GetMinPricingStartLevel() + + //if not all failed attempts of lower level are used, go back + if (num_generated_cols >= i_min_num_columns && pricing_level > 0 && ctlr->GetNumFailures(pricing_level - 1) < i_max_num_failures) { + i_pricing_start_level = pricing_level - 1; + } + + return num_generated_cols; + } + + if (v_num_failures[pricing_level] >= i_max_num_failures) { //in not standard order, the pricing level is increased in function Pricing() + i_pricing_start_level = pricing_level + 1; + } + + // sufficiently many cols generated? + if (num_generated_cols >= i_min_num_columns) + break; + + } + //// update failures and start level + //for( int i = 0; i < (int)v_hierarchy.size()-1; i++){ + // if( v_num_failures[i] >= i_max_num_failures ){ + // i_pricing_start_level = i+1; + // } + //} + return num_generated_cols; +} + /////////////////////////////////////////////////////////////////////////////// // c_MergeManagerCVRP /////////////////////////////////////////////////////////////////////////////// @@ -4089,6 +4168,10 @@ int c_SeparationProblemCVRPTW::Go(c_RMP* rmp, list<c_Constraint*>& cuts, int nod c_RMP_CVRPTW* my_rmp = (c_RMP_CVRPTW*) rmp; my_rmp->UpdateFlows(); + + if(IsFractional(my_rmp->NumVehicles()) && ctlr->BranchVehicleFirst()) + return 0; + if( node_level <= ctlr->MaxCutNodeLevel() ){ if( ctlr->UseDynamicNgNeighborhood() ){ EliminateCyclesByExtendingNeighborhood( cuts ); @@ -4122,7 +4205,7 @@ int c_SeparationProblemCVRPTW::Go(c_RMP* rmp, list<c_Constraint*>& cuts, int nod if( ctlr->UseSubsetRowCuts() ){ int factorNumSRCuts = ctlr->IsAggregated()? ctlr->PlanningHorizon() : 1; - if( node_level <= ctlr->MaxCutNodeLevel() && ctlr->NumSubsetRowCuts() * factorNumSRCuts < maxCutNumber ){ + if( node_level <= ctlr->MaxCutNodeLevel() && ctlr->NumSubsetRowCuts() * factorNumSRCuts < ctlr->MaxNumSubsetRow()){ SeparateSubSetRowCuts(rmp, cuts); } } @@ -4151,7 +4234,7 @@ int c_SeparationProblemCVRPTW::SeparateSubSetRowCuts(c_RMP* rmp, list<c_Constrai } //Overall number of subset-row cuts is limited - if(ctlr->NumSubsetRowCuts() >= maxCutNumber){ + if(ctlr->NumSubsetRowCuts() > ctlr->MaxNumSubsetRow()){ return 0; } @@ -4228,7 +4311,7 @@ int c_SeparationProblemCVRPTW::SeparateSubSetRowCuts(c_RMP* rmp, list<c_Constrai sort(violatingSubsets.begin(), violatingSubsets.end()); vector<int> v_addedSRCutsPerCustomer = vector<int>( ctlr->NumTasks(), 0 ); int factorNumSRCuts = ctlr->IsAggregated()? ctlr->PlanningHorizon() : 1; - for (int i = 0; (ctlr->NumSubsetRowCuts()+1) * factorNumSRCuts < maxCutNumber && i < (int)violatingSubsets.size() && added_cuts < ctlr->MaxNumberSRCutsPerIteration(); ++i) + for (int i = 0; (ctlr->NumSubsetRowCuts()+1) * factorNumSRCuts < ctlr->MaxNumSubsetRow() && i < (int)violatingSubsets.size() && added_cuts < ctlr->MaxNumberSRCutsPerIteration(); ++i) { bool to_add = true; for (int j = 0; j<(int)violatingSubsets[i].second.size(); j++) diff --git a/bcp_cvrptw.h b/bcp_cvrptw.h index b056882b5297e29d21b7b965f7d1bb6a97558a31..bf4daa1d6cc78f84e7d8440062262433dd1a21ec 100644 --- a/bcp_cvrptw.h +++ b/bcp_cvrptw.h @@ -24,6 +24,8 @@ using namespace CGBase; extern bool taskNetwork; extern bool schedulePartNetwork; +class c_PricingSolverHierarchyCVRPTW; + class c_ControllerCVRPTW : public c_Controller, public c_CVRPTW_Instance_With_RDC { c_Matrix<c_REF_CVRPTW*> m_REFs; int i_numSubsetRowCuts; @@ -38,6 +40,12 @@ class c_ControllerCVRPTW : public c_Controller, public c_CVRPTW_Instance_With_RD int i_numAddedColumns; bool b_aggregated; double originalUB; + int i_startHierarchyId; + + std::vector<c_PricingSolverHierarchyCVRPTW*> v_hierarchy_vec; //Work_around for ankas code in new framework + + vector<int> pricing_levels_in_hierarchies; + vector<int> v_numFailures_hierarchy; public: c_ControllerCVRPTW( string instanceFile, string scheduleFile, std::string settings_file = "settings/settings.txt" ); virtual ~c_ControllerCVRPTW(); @@ -135,6 +143,29 @@ public: c_IntParameter BranchingCustomerDayCandidates; c_BoolParameter RestrictVerticesWithDominanceCheck; c_IntParameter BranchingTieBreakerRule; + + c_BoolParameter PricingHierarchyStandardOrder; + + int GetStartHierarchy() { return i_startHierarchyId; } + void SetStartHierarchy(int hierarchyId) { i_startHierarchyId = hierarchyId; } + + int GetNumFailures(int pricingLevel) { return v_numFailures_hierarchy[pricingLevel]; } + void IncreaseNumFailures(int pricingLevel) { v_numFailures_hierarchy[pricingLevel]++; } + void ResetNumFailures() { + for (int i = 0; i < v_numFailures_hierarchy.size(); i++) + v_numFailures_hierarchy[i] = 0; + } + + // setter to overwrite pricing method + void Set_number_of_solved_pricing_problems(int new_number) { info_number_of_solved_pricing_problems = new_number; } + void Set_number_of_generated_columns(int new_number) { info_number_of_generated_columns = new_number; } + void Set_number_of_rmp_iterations(int new_number) { info_number_of_rmp_iterations = new_number; } + void Set_timer_pricing_update(double new_number) { info_timer_PricingUpdate = new_number; } + + c_IntParameter MaxNumSubsetRow; + c_BoolParameter BranchVehicleFirst; + + }; @@ -595,9 +626,17 @@ public: c_PricingSolverHierarchyCVRPTW( c_Controller* controller, int max_num_failures, int min_num_columns, int day ); const int Day(){return i_day;} - + void SetBestReducedCost(double val) { d_best_reduced_costs = val; } virtual void Update( c_BranchAndBoundNode* node ); virtual void Update( c_DualVariables* dual ); + int GetNumPricingLevels() const { return (int)v_hierarchy.size(); } + int GetPricingStartLevel() const { return i_pricing_start_level; } + void SetPricingStartLevel(int val) { i_pricing_start_level = val; } + const int GetMinNumCols() const { return i_min_num_columns; } + + //overwrite + virtual int Go(c_DualVariables* dual, list<c_ColumnPricePair>& cols_and_prices, int NumPricersUsed = MaxNumPricers); + }; diff --git a/cvrptw_ref.h b/cvrptw_ref.h index d816921ca8c433fd7fe19e8f027b73fe2c44993c..19a0f92c02434563ea75fe5bd45acb2a11716766 100644 --- a/cvrptw_ref.h +++ b/cvrptw_ref.h @@ -13,8 +13,9 @@ using namespace espprc; -const int maxCutNumber = 100; // leider anders nicht festlegbar -typedef std::bitset<maxCutNumber> sr_bitset; +//const int maxCutNumber = 100; // static version, just allow 300 at max +const int MaxSR = 300; +typedef std::bitset<MaxSR> sr_bitset; //const int numNodes = 50;// TODO: //typedef std::bitset<numNodes> node_bitset; diff --git a/settings/settings.txt b/settings/settings.txt index 45fb959dbfaa67dfe0ebc51a7b28faafe55de519..212d5721efb9a631d4e015433164da7474ebb653 100644 --- a/settings/settings.txt +++ b/settings/settings.txt @@ -2,19 +2,18 @@ %%%%%%%%%%%%%%%%%%%%%%%%% PVRP specific %%%%%%%%%%%%%%%%%%%%%%%%% % NetworkOfTasks true -RestrictVerticesWithDominanceCheck false %This is not working anymore NetworkOfScheduleParts false RegularVisits false MinimumTourDuration true UseHeuristicDominance false SeparateAggregatedSRCuts false StartWithAggregation true -BreakSymmetry false -AddColumnsOnOtherDays false +BreakSymmetry true +AddColumnsOnOtherDays true PricingHierarchyStandardOrder false % %%%%%%%%%%%%%%%%%%%%%%%%% Pricing %%%%%%%%%%%%%%%%%%%%%%%%% -HeuristicPricersNetworkSizes 5 10 20 40 10000 +HeuristicPricersNetworkSizes 5 10 20 10000 NgNeighborhoodSize 12 UseDynamicNgNeighborhood true DynamicNgNeighborhoodUB 18 @@ -24,7 +23,7 @@ PricingHierarchyMinNumColsToGenerate 1 %%%%%%%%%%%%%%%%%%%%%%%%% info %%%%%%%%%%%%%%%%%%%%%%%%% % -InfoLevel 2 +InfoLevel 1 InfoStatisticsLevel 1 InfoDottyOutput false InfoGnuplotOutput false @@ -33,7 +32,7 @@ InfoPrintBestSolution false InfoPrintOverallBestSolution true InfoConvergency false InfoOutputFileName solutions.csv -MaxSolutionTimeSec 3540 +MaxSolutionTimeSec 3600 ReloadSettings false % %%%%%%%%%%%%%%%%%%%%%%%%% global settings %%%%%%%%%%%%%%%%%%%%%%%%% @@ -48,7 +47,10 @@ Stabilization false %%%%%%%%%%%%%%%%%%%%%%%%% cutting planes %%%%%%%%%%%%%%%%%%%%%%%%% % CuttingPlanes true +BranchVehicleFirst true +MaxCutNodeLevel 1 UseSubsetRowCuts true +MaxNumSubsetRow 300 MaxNumberSRCutsPerIteration 4 MaxSRCutsPerCustomerPerIteration 3 UseCapacityCuts false @@ -58,7 +60,6 @@ KPathMaxSizeOfSets 15 KPathMaxInclusion 1 KPathRestarts 10 CutTolerance 0.1 -MaxCutNodeLevel 3 % %%%%%%%%%%%%%%%%%%%%%%%%% Branching %%%%%%%%%%%%%%%%%%%%%%%%% % @@ -66,12 +67,15 @@ Branching true BranchingNodeSelection BestFirst BranchingCustomerDayCandidates 1 BranchingTieBreakerRule 2 -StrongBranching false -StrongBranchingUptoLevel 40 -StrongBranchingNumCandidates 3 -StrongBranchingMinNumCandidates 3 -StrongBranchingNumCandidatesDecreasePerLevel .1 -StrongBranchingSolveExact true +%%%%Strong Brnaching -> needs to be corretlly implemented first +StrongBranching false +PricersUsedForStrongBranching 2 +StrongBranchingRule Product +StrongBranchingUptoLevel 10 +StrongBranchingNumCandidates 10 +StrongBranchingMinNumCandidates 5 +StrongBranchingNumCandidatesDecreasePerLevel 1.0 + % %%%%%%%%%%%%%%%%%%%%%%%%% MIP as heuristic %%%%%%%%%%%%%%%%%%%%%%%%% % @@ -83,8 +87,9 @@ UseMIPSolverAtTheEnd true - - +RestrictVerticesWithDominanceCheck false %This is not working anymore +%StrongBranchingSolveExact true %Does not exist anymore +%%%% %%%%old?%%%% %AddOnlyActiveAggregatedSRCuts false %GenerateSingleSRCutsAfterDisaggregation false