R1Cs: RC Updater¶
Overview¶
The file packages/rank1_cuts/chg_rc_getter/include/rank1_rc_controller.hpp
defines the controller and utilities for managing Rank-1 cut pricing (in labeling) statistics and states within the RouteOpt software package.
This header is pivotal for updating reduced cost (RC) information, copying pricing statistics, updating state values, performing dominance checks, concatenating state information during the labeling process.
License¶
This software is licensed under GPL-3.0.
File Contents¶
This header file comprises the following key components:
Structures and Utility Functions
R1CPricingStat
Structure holding Rank-1 cut pricing statistics, including:
num
Number of valid cuts.
valid_cut_idx
Pointer to an array of valid cut indices.
cut_map
Pointer to the complete cut map array.
copyFrom()
Method to copy pricing statistics from another instance.
R1CUseStates
Structure representing the usage states for Rank-1 cuts, including:
union_map
Bitset representing the union (C+M) mapping (1 indicates presence of a cut).
v_union_mem
Vector representing union memory for cuts.
sparse
Sparse representation of states as a vector of pairs.
sparse_map
Bitset for the sparse mapping (specific to C).
Controller: Rank1RCController
The
Rank1RCController
class provides functionality to:Initialize label memory for pricing statistics via
initializeLabel()
.Retrieve Rank-1 dual values from the column generation (CG) process using
getRank1DualsInCG()
.Update Rank-1 cut states with
updateR1CStates()
.Check dominance between pricing statistics with
doR1CDominance()
.Concatenate state information via
concatenateR1CStates()
.Assign contiguous label memory to label objects using the templated method
assignLabelMem()
.
Controller: Rank1RCController¶
Constructor¶
data_shared
Input: A reference to a shared Rank-1 cuts data object of type
Rank1CutsDataShared
.Meaning: Provides precomputed multipliers and metadata required for generating and updating Rank-1 cut states.
Member Functions¶
initializeLabel()
Static Method Initializes the label fields of a given pricing statistic by filling the entire cut_map array with zeros.
getRank1DualsInCG()
Functionality: Update the dual map for a given set of Rank-1 cuts using a provided π-vector.
updateR1CStates()
Functionality: Updates the RC and produces new pricing statistics by transferring state information from a source customer to a target customer.
doR1CDominance()
Functionality: Checks whether the updated pricing statistics dominate the input statistics by comparing a computed gap value. Returns true if the dominance condition is satisfied.
concatenateR1CStates()
Functionality: Concatenates input state information into output pricing statistics based on a required value. This process is crucial for combining state information across different customers.
assignLabelMem()
Templated Method Assigns contiguous memory space for the cut_map and valid_cut_idx fields for an array of label objects.
Header Codes¶
Below is an excerpt from rank1_rc_controller.hpp
that illustrates the structure and functionality of the Rank1RCController class:
#ifndef ROUTE_OPT_RANK1_RC_CONTROLLER_HPP
#define ROUTE_OPT_RANK1_RC_CONTROLLER_HPP
#include <algorithm>
#include "rank1_macro.hpp"
#include "route_opt_macro.hpp"
namespace RouteOpt::Rank1Cuts::RCGetter {
struct R1CPricingStat {
int num{};
int *valid_cut_idx{};
int *cut_map{};
void copyFrom(const R1CPricingStat &other) {
num = other.num;
std::copy_n(other.valid_cut_idx, num, valid_cut_idx);
std::copy_n(other.cut_map, MAX_NUM_R1CS_IN_PRICING, cut_map);
}
};
struct R1CUseStates {
r1cIndex union_map{};
std::vector<int> v_union_mem;
std::vector<std::pair<int, int>> sparse;
r1cIndex sparse_map{};
};
class Rank1RCController {
public:
explicit Rank1RCController(Rank1CutsDataShared &data_shared)
: data_shared_ref(std::ref(data_shared)) {
}
static void initializeLabel(const R1CPricingStat &r1c) {
std::fill_n(r1c.cut_map, MAX_NUM_R1CS_IN_PRICING, 0);
}
void getRank1DualsInCG(const std::vector<R1c> &cuts,
const std::vector<double> &pi_vector);
void updateR1CStates(double &rc, R1CPricingStat &out_states,
const R1CPricingStat &in_states,
int from,
int to);
bool doR1CDominance(double &gap,
const R1CPricingStat &out_states,
const R1CPricingStat &in_states);
bool concatenateR1CStates(double &rc, double req, R1CPricingStat &out_states,
const R1CPricingStat &in_states, int out, int in);
template<typename T, typename R1cPtr>
void assignLabelMem(T *all_label, size_t label_assign, R1cPtr r1c_ptr) {
if (all_label == nullptr)
THROW_RUNTIME_ERROR("all_label is nullptr");
delete[] label_int_space;
size_t constexpr label_int_space_len = MAX_NUM_R1CS_IN_PRICING + MAX_POSSIBLE_NUM_R1CS_FOR_VERTEX;
label_int_space = new int[label_int_space_len * label_assign];
size_t cut_map_beg = 0;
for (size_t i = 0; i < label_assign; ++i) {
auto &r1c = all_label[i].*r1c_ptr;
r1c.cut_map = label_int_space + cut_map_beg;
cut_map_beg += MAX_NUM_R1CS_IN_PRICING;
r1c.valid_cut_idx = label_int_space + cut_map_beg;
cut_map_beg += MAX_POSSIBLE_NUM_R1CS_FOR_VERTEX;
}
}
Rank1RCController() = delete;
~Rank1RCController() {
delete[] label_int_space;
}
private:
int *label_int_space{};
std::vector<R1CUseStates> cg_v_cut_map{};
std::vector<std::vector<std::vector<int>>> cg_v_v_use_states{};
std::vector<int> cg_r1c_denominator{};
std::vector<double> rank1_dual{};
std::vector<double> revised_rank1_dual{};
const std::reference_wrapper<Rank1CutsDataShared> data_shared_ref;
};
} // namespace RouteOpt::Rank1Cuts::RCGetter
#endif // ROUTE_OPT_RANK1_RC_CONTROLLER_HPP
Usage Example¶
Below is an example demonstrating how to use the Rank1RCController in RouteOpt. This example shows how to initialize shared data, prepare dummy pricing statistics, retrieve dual values, update states, and perform dominance and concatenation checks.
#include <vector>
#include <iostream>
#include "rank1_rc_controller.hpp"
#include "rank1_macro.hpp"
#include "solver.hpp"
using namespace RouteOpt::Rank1Cuts;
using namespace RouteOpt::Rank1Cuts::RCGetter;
int main() {
// Initialize shared Rank-1 cuts data with an instance dimension (e.g., 5)
Rank1CutsDataShared sharedData(5);
// Create an instance of the Rank1RCController with the shared data
Rank1RCController rcController(sharedData);
// assign label memory for a vector of labels (e.g., 10 labels), assuming Label is a struct with r1c as a member
auto all_label = new Label[10];
rcController.assignLabelMem(all_label, 10, &Label::r1c);
// Prepare a dummy R1CPricingStat for demonstration
R1CPricingStat pricingStat;
// Allocate memory for valid_cut_idx and cut_map as needed, for example:
// pricingStat.valid_cut_idx = new int[some_length];
// pricingStat.cut_map = new int[MAX_NUM_R1CS_IN_PRICING];
// Initialize the label fields of pricingStat (set all values in cut_map to zero)
Rank1RCController::initializeLabel(pricingStat);
// Prepare a dummy π-vector (dual prices)
std::vector<double> piVector = {1.0, 0.5, 0.2, 0.8, 0.3};
// Assume an empty vector of Rank-1 cuts for demonstration
std::vector<R1c> cuts;
// Retrieve dual values from the column generation process
rcController.getRank1DualsInCG(cuts, piVector);
// Update Rank-1 cut states (e.g., transfer state from customer 1 to customer 2)
double rc = 0.0;
R1CPricingStat newPricingStat;
// Ensure newPricingStat is allocated and initialized appropriately.
rcController.updateR1CStates(rc, newPricingStat, pricingStat, 1, 2);
// Perform a dominance check between the updated and original pricing statistics
double gap = -10.0; // Example gap value
bool isDominant = rcController.doR1CDominance(gap, newPricingStat, pricingStat);
std::cout << "Dominance check result: "
<< (isDominant ? "Dominant" : "Not Dominant") << std::endl;
// Concatenate state information with a required value (example: 1.5)
bool concatenated = rcController.concatenateR1CStates(rc, 1.5, newPricingStat, pricingStat, 2, 1);
std::cout << "State concatenation "
<< (concatenated ? "succeeded" : "failed") << std::endl;
// Clean up any dynamically allocated memory if necessary.
// The destructor of rcController will automatically free label_int_space.
return 0;
}
Note
For a deeper understanding of the Rank-1 RC Controller, explore the application source code under
packages/application/cvrp/src
using an IDE such as CLion.
If you have any questions, please feel free to contact me at you.z@ufl.edu or reach out via Group Chat.
Conclusion¶
The Rank1RCController module in RouteOpt offers a comprehensive framework for managing Rank-1 cut pricing statistics and states. By providing functionality for dual value retrieval, state updates, dominance checks, state concatenation, and memory assignment, this module enables effective management of reduced cost information during the labeling process in complex routing problems.