Solver as a Service
Sign Up Now →Sign Up Now

Pricing a consolidated tariff: measures and pooled objectives

Preview

Some tariffs charge a group for a function of several totals, not for one sum. Air freight is the common case. A carrier bills a consolidation at chargeable weight, the greater of the actual weight and the volumetric weight (volume x 167 kg per m3), times the departure’s rate. No single-attribute term can say "the greater of two sums". Two generic features can.

A measures: block names per-group quantities. Aggregates (sum, count, max, min) read one entity attribute, with an optional constant scale. Expressions combine other measures with + - * and max()/min():

measures:
  actual_kg:
    collect: sum
    of: weight_kg
  volumetric_kg:
    collect: sum
    of: volume_m3
    scale: 167
  chargeable_kg:
    expr: "max(actual_kg, volumetric_kg)"

Every measure is total: an empty group is 0, and there is no division. Every measure is also typed: a missing or non-numeric value in the data is an error naming the measure, attribute and entity, never a silent zero. The registration gate refuses a block that does not compile. That covers an unknown name, a cycle, a scale that is not a real number, or disallowed syntax, and each refusal is a measure_invalid error.

Two objective terms price a measure:

  • sum_group_measure prices each used group: the measure over its members, times group_attribute (optional). It is additive per group, so the incremental scorer keeps it in its ledger.

  • sum_pooled_measure prices pools of used groups that share a pool_by value, as one. The measure is taken over the pool’s combined members, times group_attribute, which every used group in the pool must carry with the same value. Positions on one departure are billed together; billing each position separately would overcharge.

objectives:
  freight_cost:
    name: "Chargeable weight per departure x the departure's rate"
    term: sum_pooled_measure
    sense: minimize
    weight: 1.0
    default_enabled: true
    parameters:
      measure: chargeable_kg
      pool_by: departure_id
      group_attribute: rate_per_kg

The gate refuses an enabled objective that names an undeclared measure, with an objective_unknown_measure error. A disabled one gets a warning, so the typo shows before anyone enables it. A used group whose multiplier is missing or non-numeric is an error at solve time, never priced at a default.

The complete working manifest is manifests/templates/air_consolidation_golden.yaml. It also declares total_over_entities: false and an unassigned_cost, so a consignment that no departure can legally take is named unplaced rather than forced into a position that breaks a rule. After the search, a last-resort pass offers every member of a group still breaking an eligibility or hard rule each other group. It unplaces the member only if no other group improves the plan.