Skip to content

Commit

Permalink
package GetFillMass also returns number of packages at that fill mass
Browse files Browse the repository at this point in the history
  • Loading branch information
nuclearkatie committed Aug 28, 2024
1 parent 5263f11 commit d8e60f2
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Since last release
* Define constants ``CY_LARGE_DOUBLE``, ``CY_LARGE_INT``, and ``CY_NEAR_ZERO`` (#1757)
* Warning and limits on number of packages that can be created from a resource at once (#1771)
* Use keep_packaging instead of unpackaged in ResBuf (#1778)
* Package GetFillMass returns fill mass and number of packages filled at that mass (#1790)

**Removed:**

Expand Down
14 changes: 11 additions & 3 deletions src/package.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ Package::Ptr& Package::unpackaged() {
return unpackaged_;
}

double Package::GetFillMass(double qty) {
std::pair<double, int> Package::GetFillMass(double qty) {
if (qty < fill_min_) {
// less than one pkg of material available
return 0;
return std::pair<double, int> (0, 0);
}

double fill_mass;
int num_at_fill_mass;

if (strategy_ == "first") {
fill_mass = fill_max_;
} else if (strategy_ == "equal") {
Expand All @@ -49,7 +51,13 @@ double Package::GetFillMass(double qty) {
fill_mass = fill_max_;
}
}
return std::min(qty, fill_mass);
fill_mass = std::min(qty, fill_mass);
if (fill_mass >= fill_min_) {
num_at_fill_mass = static_cast<int>(std::floor(qty / fill_mass));
return std::pair<double, int>(fill_mass, num_at_fill_mass);
} else {
return std::pair<double, int>(0, 0);
}
}

Package::Package(std::string name, double fill_min, double fill_max,
Expand Down
11 changes: 7 additions & 4 deletions src/package.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ class Package {
double fill_max = std::numeric_limits<double>::max(),
std::string strategy = "first");

/// Returns optimal fill mass for a resource to be packaged. Can be used
/// to determine how to respond to requests for material, and to actually
/// package and send off trades.
/// Returns optimal fill mass for a resource to be packaged, and number of
/// packages that can be crated at that fill mass (note that up to one
/// additional package may be possible to create with a lower fill mass,
/// which much be checked separately).
/// Can be used to determine how to respond to requests for material, and
/// to actually package and send off trades.
/// Packaging strategy "first" simply fills the packages one by one to the
/// maximum fill. Therefore, it should always try to max fill.
/// Packaging strategy "equal" tries to fill all packages to the same mass.
Expand All @@ -41,7 +44,7 @@ class Package {
/// quantity = 5, fill_min = 3, fill_max = 4. num_min_fill = floor(5/3) = 1,
/// num_max_fill = ceil(5/4) = 2. num_min_fill < num_max_fill, so fill to
/// the max.
double GetFillMass(double qty);
std::pair<double, int> GetFillMass(double qty);

// returns package name
std::string name() const { return name_; }
Expand Down
5 changes: 3 additions & 2 deletions src/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,15 @@ std::vector<typename T::Ptr> Resource::Package(Package::Ptr pkg) {
std::vector<typename T::Ptr> ts_pkgd;
typename T::Ptr t_pkgd;

double fill_mass = pkg->GetFillMass(quantity());
std::pair<double, int> fill = pkg->GetFillMass(quantity());
double fill_mass = fill.first;
if (fill_mass == 0) {
return ts_pkgd;
}

// Check if the number of packages is within the limits, including if
// int overflow is reached
int approx_num_pkgs = quantity() / fill_mass;
int approx_num_pkgs = fill.second;
Package::ExceedsSplitLimits(approx_num_pkgs);

while (quantity() > 0 && quantity() >= pkg->fill_min()) {
Expand Down
13 changes: 9 additions & 4 deletions src/toolkit/matl_sell_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ void MatlSellPolicy::set_package(std::string x) {
// if no real context, only unpackaged can be used (keep default)
if (manager() != NULL) {
Package::Ptr pkg = manager()->context()->GetPackage(x);
double pkg_fill = pkg->GetFillMass(quantize_);
std::pair<double, int> fill = pkg->GetFillMass(quantize_);
double pkg_fill = fill.first;
if ((pkg->name() != Package::unpackaged_name()) && (quantize_ > 0) &&
(std::fmod(quantize_, pkg_fill) > 0)) {
std::stringstream ss;
Expand All @@ -63,7 +64,8 @@ void MatlSellPolicy::set_transport_unit(std::string x) {
if (manager() != NULL) {
TransportUnit::Ptr tu = manager()->context()->GetTransportUnit(x);

int num_pkgs = quantize_ / (package_->GetFillMass(quantize_));
std::pair<double, int> fill = package_->GetFillMass(quantize_);
int num_pkgs = fill.second;
int max_shippable = tu->MaxShippablePackages(num_pkgs);

if ((tu->name() != TransportUnit::unrestricted_name()) && quantize_ > 0 &&
Expand Down Expand Up @@ -197,9 +199,12 @@ std::set<BidPortfolio<Material>::Ptr> MatlSellPolicy::GetMatlBids(
for (rit = requests.begin(); rit != requests.end(); ++rit) {
req = *rit;
qty = std::min(req->target()->quantity(), limit);
bid_qty = excl ? quantize_ : package_->GetFillMass(qty);
std::pair<double, int> fill = package_->GetFillMass(qty);
bid_qty = excl ? quantize_ : fill.first;
if (bid_qty != 0) {
n_full_bids = static_cast<int>(std::floor(qty / bid_qty));
std::cerr << "bid_qty: " << bid_qty << std::endl;
std::cerr << "full bids: " << fill.second << std::endl;
n_full_bids = excl ? std::floor(qty / quantize_) : fill.second;

// Throw if number of bids above limit or if casting to int caused
// overflow to negative int limit
Expand Down
48 changes: 39 additions & 9 deletions tests/package_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,56 @@ TEST(PackageTests, GetPackageFillMass) {
Package::Ptr q = Package::Create("bar", min, max, "equal");
Package::Ptr r = Package::Create("baz", tight_min, max, "equal");

std::pair<double, int> p_fill, q_fill, r_fill;

double exp;

// no fit
double no_fit = 0.05;
EXPECT_EQ(0, p->GetFillMass(no_fit));
EXPECT_EQ(0, q->GetFillMass(no_fit));
p_fill = p->GetFillMass(no_fit);;
EXPECT_EQ(0, p_fill.first);
EXPECT_EQ(0, p_fill.second);

q_fill = q->GetFillMass(no_fit);
EXPECT_EQ(0, q_fill.first);
EXPECT_EQ(0, q_fill.second);

// perfect fit
double perfect_fit = 0.9;
EXPECT_EQ(perfect_fit, p->GetFillMass(perfect_fit));
EXPECT_EQ(perfect_fit, q->GetFillMass(perfect_fit));
p_fill = p->GetFillMass(perfect_fit);
EXPECT_EQ(perfect_fit, p_fill.first);
EXPECT_EQ(1, p_fill.second);

q_fill = q->GetFillMass(perfect_fit);
EXPECT_EQ(perfect_fit, q_fill.first);
EXPECT_EQ(1, q_fill.second);

// partial fit
double partial_fit = 1;
EXPECT_EQ(max, p->GetFillMass(partial_fit));

p_fill = p->GetFillMass(partial_fit);
EXPECT_EQ(max, p_fill.first);
EXPECT_EQ(1, p_fill.second);

q_fill = q->GetFillMass(partial_fit);
exp = partial_fit / 2;
EXPECT_EQ(exp, q->GetFillMass(partial_fit));
EXPECT_EQ(max, r->GetFillMass(partial_fit));
EXPECT_EQ(exp, q_fill.first);
EXPECT_EQ(2, q_fill.second);

r_fill = r->GetFillMass(partial_fit);
EXPECT_EQ(max, r_fill.first);
EXPECT_EQ(1, r_fill.second);

// two full packages for equal, only one for
double two_packages = 1.4;
EXPECT_EQ(max, p->GetFillMass(two_packages));

p_fill = p->GetFillMass(two_packages);
EXPECT_EQ(max, p_fill.first);
EXPECT_EQ(1, p_fill.second);

q_fill = q->GetFillMass(two_packages);
exp = two_packages / 2;
EXPECT_EQ(exp, q->GetFillMass(two_packages));
EXPECT_EQ(exp, q_fill.first);
}

TEST(PackageTests, CreateTransportUnit) {
Expand Down

0 comments on commit d8e60f2

Please sign in to comment.