Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use costs_with_surtax in infra strategy #229

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/reference/koswat_strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ For example, given the results of the [clustering example](#clustering-example)

#### Cluster common available measures' cost

Once we have calculated a [cluster's option](#cluster-options) we can determine whether this cluster should be consider as a valid one. This estimation is based on the __cheapest reinforcement's cost__, and to get this value we first need to know which reinforcements are available at all the locations of this option.
Once we have calculated a [cluster's option](#cluster-options) we can determine whether this cluster should be consider as a valid one. This estimation is based on the __cheapest reinforcement's cost__ (including surtax), and to get this value we first need to know which reinforcements are available at all the locations of this option.

We will store this value in the `InfraClusterOption.cluster_costs`. In the current implementation, these costs are added to the `InfraClusterOption` together with the cluster's data (`list[InfraCluster]`).

Expand All @@ -338,15 +338,15 @@ __Conditions__:

Following the [options example](#cluster-option-example) we can estimate some fictional costs based on the following tables (if a type / location is not mentioned, then assume its cost is zero (`0`)):

| Index | Reinforcement type | base cost |
| Index | Reinforcement type | base cost incl. surtax |
| ---- | ---- |---- |
| 0 | Soil reinforcement | 42 |
| 1 | Vertical Piping Solution | 420 |
| 2 | Piping Wall | 4.200 |
| 3 | Stability Wall | 42.000 |
| 4 | Cofferdam | 420.000 |

| Location | Reinforcement indices | Infrastructure cost |
| Location | Reinforcement indices | Infrastructure cost incl. surtax |
| ---- | ---- | ---- |
| Location_000 | 0, 1 | 4.200.000 |
| Location_005 | 0, 1, 2, 3 | 4.200.000 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def create_strategy_location_reinforcement_costs():
reinforcement_type=type(
locations_profile.profile_cost_report.reinforced_profile
),
base_costs=locations_profile.profile_cost_report.total_cost,
base_costs_with_surtax=locations_profile.profile_cost_report.total_cost_with_surtax,
)

Expand Down Expand Up @@ -85,7 +84,6 @@ def get_reinforcement(
)
return StrategyReinforcementInput(
reinforcement_type=reinforcement_cost.reinforcement_type,
base_costs=reinforcement_cost.base_costs,
base_costs_with_surtax=reinforcement_cost.base_costs_with_surtax,
ground_level_surface=_reinforcement.new_ground_level_surface,
)
Expand Down
11 changes: 7 additions & 4 deletions koswat/strategies/strategy_location_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ class StrategyLocationInput:
@property
def cheapest_reinforcement(self) -> StrategyReinforcementTypeCosts:
"""
Gets the `StrategyLocationReinforcementCosts` with the lowest `total_costs` value.
Gets the `StrategyLocationReinforcementCosts` with the lowest `total_costs_with_surtax` value.

Returns:
StrategyLocationReinforcementCosts: The cheapest reinforcement for this location.
"""
return min(self.strategy_reinforcement_type_costs, key=lambda x: x.total_costs)
return min(
self.strategy_reinforcement_type_costs,
key=lambda x: x.total_costs_with_surtax,
)

@property
def available_measures(self) -> list[type[ReinforcementProfileProtocol]]:
Expand Down Expand Up @@ -53,11 +56,11 @@ def get_reinforcement_costs(
ValueError: The reinforcement type is not available.

Returns:
float: The reinforcement costs.
float: The reinforcement costs with surtax.
"""
for _srtc in self.strategy_reinforcement_type_costs:
if _srtc.reinforcement_type == reinforcement_type:
return _srtc.total_costs
return _srtc.total_costs_with_surtax
raise ValueError(
f"Reinforcement {reinforcement_type.output_name} not available, costs cannot be computed."
)
Expand Down
4 changes: 2 additions & 2 deletions koswat/strategies/strategy_location_reinforcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ def current_selected_measure(self) -> type[ReinforcementProfileProtocol]:
@property
def current_cost(self) -> float:
"""
Estimates the costs at this location for the given `current_selected_measure`.
Estimates the costs with surtax at this location for the given `current_selected_measure`.
"""
if not self.current_selected_measure or not self.strategy_location_input:
return 0.0
for _srtc in self.strategy_location_input.strategy_reinforcement_type_costs:
if _srtc.reinforcement_type == self.current_selected_measure:
return _srtc.total_costs
return _srtc.total_costs_with_surtax
return 0.0

@property
Expand Down
1 change: 0 additions & 1 deletion koswat/strategies/strategy_reinforcement_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
@dataclass
class StrategyReinforcementInput:
reinforcement_type: type[ReinforcementProfileProtocol]
base_costs: float = 0.0
base_costs_with_surtax: float = 0.0
ground_level_surface: float = 0.0
10 changes: 5 additions & 5 deletions koswat/strategies/strategy_reinforcement_type_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
@dataclass
class StrategyReinforcementTypeCosts:
reinforcement_type: type[ReinforcementProfileProtocol]
base_costs: float = 0.0
base_costs_with_surtax: float = 0.0
infrastructure_costs: float = 0.0
infrastructure_costs_with_surtax: float = 0.0

@property
def total_costs(self) -> float:
def total_costs_with_surtax(self) -> float:
"""
The simple addition of the base costs and the possible
related infrastructure costs.
related infrastructure costs, both including surtax.

Returns:
float: The total costs when applying this reinforcement.
float: The total costs with surtax when applying this reinforcement.
"""
return self.base_costs + self.infrastructure_costs
return self.base_costs_with_surtax + self.infrastructure_costs_with_surtax
10 changes: 7 additions & 3 deletions tests/strategies/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ def _get_example_strategy_input() -> Iterator[StrategyInput]:
_levels_data = [
StrategyReinforcementTypeCosts(
reinforcement_type=_reinforcement,
base_costs=(10**_idx) * 42.0,
base_costs_with_surtax=(10**_idx) * 42.0 * 2,
infrastructure_costs=(10 ** (len(_reinforcement_type_default_order) - 1))
* 42.0
* 42.0,
infrastructure_costs_with_surtax=(
10 ** (len(_reinforcement_type_default_order) - 1)
)
* 84.0
if _idx in [0, 1, 3]
else 0.0, # Dramatic infra costs so they move to where we want
)
Expand All @@ -69,7 +72,6 @@ def _get_example_strategy_input() -> Iterator[StrategyInput]:
_strategy_reinforcements = [
StrategyReinforcementInput(
reinforcement_type=_rtc.reinforcement_type,
base_costs=_rtc.base_costs,
base_costs_with_surtax=_rtc.base_costs_with_surtax,
ground_level_surface=10.0 * (len(_reinforcement_type_default_order) - _idx),
)
Expand Down Expand Up @@ -157,6 +159,7 @@ def _get_example_location_reinforcements_with_selected_subclustering(
for _sl in example_strategy_input.strategy_locations:
for _cost in _sl.strategy_reinforcement_type_costs:
_cost.infrastructure_costs = 0
_cost.infrastructure_costs_with_surtax = 0

def modify_costs_to(
location: StrategyLocationInput,
Expand All @@ -173,6 +176,7 @@ def modify_costs_to(
_costs.infrastructure_costs = (
10 ** len(_reinforcement_type_default_order)
) * 42
_costs.infrastructure_costs_with_surtax = _costs.infrastructure_costs * 2

# We force the first cluster from index 0 to index 2
modify_costs_to(example_strategy_input.strategy_locations[0], 2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,31 +171,36 @@ def _get_infra_cluster_for_subclusters_fixture(self) -> Iterator[InfraCluster]:
strategy_reinforcement_type_costs=[
StrategyReinforcementTypeCosts(
SoilReinforcementProfile,
base_costs=42,
base_costs_with_surtax=42,
infrastructure_costs=420000,
infrastructure_costs_with_surtax=420000,
),
StrategyReinforcementTypeCosts(
PipingWallReinforcementProfile,
base_costs=4200,
base_costs_with_surtax=4200,
infrastructure_costs=420,
infrastructure_costs_with_surtax=420,
),
# Costs are too big, it won't be considered
StrategyReinforcementTypeCosts(
VPSReinforcementProfile,
base_costs=42000000,
base_costs_with_surtax=42000000,
infrastructure_costs=4200000,
infrastructure_costs_with_surtax=4200000,
),
# Not present at all locations.
StrategyReinforcementTypeCosts(
StabilityWallReinforcementProfile,
base_costs=42,
base_costs_with_surtax=42,
infrastructure_costs=42,
infrastructure_costs_with_surtax=42,
),
# Cheapest of all, but only present at one location.
StrategyReinforcementTypeCosts(
CofferdamReinforcementProfile,
base_costs=42,
base_costs_with_surtax=42,
infrastructure_costs=0,
infrastructure_costs_with_surtax=0,
),
],
)
Expand Down