Sensor Positioning (SP) API Reference
Data
Data model for the Sensor Positioning (SP) use case.
SppData
Bases: UcData
Materialized coverage representation for Sensor Positioning.
This variant assumes coverage was precomputed (e.g., from geometry)
and stored as a boolean matrix: targets x positions. Fixed-on/off sets
(fixed_on, fixed_off) capture degree-1/dominated preprocessing decisions.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
Literal['sensor_position_problem']
|
Identifier. |
position_ids |
list[str]
|
Identifiers for candidate sensor placements. |
target_ids |
list[str]
|
Identifiers for targets/street points to cover. |
coverage |
NumPyArray
|
Boolean matrix shape (n_targets, n_positions): coverage[t, p] is True if position p covers target t. |
position_costs |
NumPyArray
|
Length n_positions; cost of activating each position (default 1). |
min_coverage |
list[int]
|
Required coverage per target (broadcasted from int if needed). |
budget |
float | None
|
Optional cost budget (<= constraint). |
max_positions |
int | None
|
Optional cardinality cap. |
incompatibilities |
list[tuple[int, int]]
|
Pairwise exclusions between positions. |
must_select |
list[int]
|
Positions that must be activated. |
forbidden |
list[int]
|
Positions that must stay deactivated. |
fixed_on |
list[int]
|
Positions forced to 1 from preprocessing (e.g., degree-1 reductions). |
fixed_off |
list[int]
|
Positions forced to 0 from preprocessing (e.g., dominated reductions). |
uncoverable_targets |
list[int] | None
|
Target indices that cannot be covered by any candidate sensor. |
cost_weight |
float
|
Weight on cost term (default 1.0). |
proximity_penalty_weight |
float
|
Optional weight for future pairwise penalties (not used yet). |
dropped_dominated_positions |
NumPyArray | None
|
Display-only geometry for dominated dropped lidars. |
dropped_degree1_positions |
NumPyArray | None
|
Display-only geometry for degree-1 dropped lidars. |
dropped_target_positions |
NumPyArray | None
|
Display-only geometry for targets removed by degree-1 reductions. |
walls |
list[WallLike] | None
|
Optional wall geometry as tuples in this order:
|
group_ids |
list[str | None]
|
Optional mutual-exclusion groups (variants) per position; same group means at most one. |
lidar_params |
list[dict] | None
|
Per-position coverage overrides (max_radius, half_horizontal_angle, max_vert_angle, min_vert_angle). |
position_metadata |
list[dict] | None
|
Display metadata per position (labels, source, groupId, coverage params, variantOf, cost). |
to_string() -> str
Summarize core counts and reduction metadata.
to_problem_dict(*, include_metadata: bool = True, include_coverage: bool = False) -> dict[str, Any]
Convert the instance to the enriched problem dictionary format.
save_to_json(path: str | Path, *, include_metadata: bool = True, include_coverage: bool = False) -> Path
Persist the problem dictionary to JSON on disk.
with_coverage(coverage: np.ndarray) -> SppData
Return a new instance with updated coverage while retaining metadata.
plot(*, ax: Axes | None = None, show_walls: bool = True, show_targets: bool = True, show_uncoverable_targets: bool = False, show_dropped_dominated_sensors: bool = True, show_dropped_degree1_sensors: bool = True, show_dropped_targets: bool = True, show_candidate_sensors: bool = True, show_coverage_rays: bool = False, show_sensor_headings: bool = True) -> Axes
Plot the SP problem structure on the provided axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Axes | None
|
Matplotlib axes to draw on. If |
None
|
show_walls
|
bool
|
Draw walls and wall polygon. |
True
|
show_targets
|
bool
|
Draw target points. |
True
|
show_uncoverable_targets
|
bool
|
Highlight uncoverable targets. |
False
|
show_dropped_dominated_sensors
|
bool
|
Draw dominated dropped sensors. |
True
|
show_dropped_degree1_sensors
|
bool
|
Draw degree-1 dropped sensors. |
True
|
show_dropped_targets
|
bool
|
Draw dropped targets. |
True
|
show_candidate_sensors
|
bool
|
Draw candidate sensors. |
True
|
show_coverage_rays
|
bool
|
Draw all coverage rays. |
False
|
show_sensor_headings
|
bool
|
Draw sensor heading arrows. |
True
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes with the plot. |
Raises:
| Type | Description |
|---|---|
InvalidProblemStructureError
|
If required geometry is missing ( |
generate_random(n_positions: int = 10, n_targets: int = 20, density: float = 0.2, seed: int | None = None) -> SppData
staticmethod
Create a random SP instance with guaranteed coverable targets.
Formulation
Formulation for the Sensor Positioning (SP) use case.
SppFormulation
Bases: UcFormulation[SppData, SppSolution]
Min-cost set-cover style formulation using materialized coverage.
to_string(data: SppData) -> str
staticmethod
Return a text summary of the formulated model inputs.
formulate(data: SppData) -> Model
staticmethod
Build the mixed-integer model for the SP instance.
interpret(solution: Solution, data: SppData) -> SppSolution
staticmethod
Map solver output back into an SpSolution with coverage metrics.
Solution
Solution model for the Sensor Positioning use case.
SppSolution
Bases: UcSolution
Selected positions and coverage metrics.
to_string() -> str
Return a formatted summary of the solution.
print() -> str
Return the string representation (alias for to_string).
plot(data: SppData | None = None, *, ax: Axes | None = None, show_walls: bool = True, show_targets: bool = True, show_uncoverable_targets: bool = False, show_dropped_dominated_sensors: bool = True, show_dropped_degree1_sensors: bool = True, show_dropped_targets: bool = True, show_candidate_sensors: bool = True, show_selected_sensors: bool = True, show_covered_targets: bool = True, show_uncovered_targets: bool = True, show_coverage_rays_all: bool = False, show_coverage_rays_selected: bool = False, show_sensor_headings: bool = True) -> Axes
Plot the SP solution structure on the provided axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
SppData | None
|
Problem data used for geometry and coverage information. |
None
|
ax
|
Axes | None
|
Matplotlib axes to draw on. If |
None
|
show_walls
|
bool
|
Draw walls and wall polygon. |
True
|
show_targets
|
bool
|
Draw target points. |
True
|
show_uncoverable_targets
|
bool
|
Highlight uncoverable targets. |
False
|
show_dropped_dominated_sensors
|
bool
|
Draw dominated dropped sensors. |
True
|
show_dropped_degree1_sensors
|
bool
|
Draw degree-1 dropped sensors. |
True
|
show_dropped_targets
|
bool
|
Draw dropped targets. |
True
|
show_candidate_sensors
|
bool
|
Draw non-selected candidate sensors. |
True
|
show_selected_sensors
|
bool
|
Draw selected sensors. |
True
|
show_covered_targets
|
bool
|
Draw covered targets. |
True
|
show_uncovered_targets
|
bool
|
Draw uncovered targets. |
True
|
show_coverage_rays_all
|
bool
|
Draw all target-to-candidate coverage rays. |
False
|
show_coverage_rays_selected
|
bool
|
Draw target-to-selected coverage rays. |
False
|
show_sensor_headings
|
bool
|
Draw sensor heading arrows. |
True
|
Returns:
| Type | Description |
|---|---|
Axes
|
The axes with the plot. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
InvalidProblemStructureError
|
If required geometry is missing on |
DataShapeMismatchError
|
If |
Instance
Instance model for Sp use case.
SppInstance
Bases: UcInstance[SppData, SppFormulation, SppSolution]
Instance combining data and formulation for Sp.
Collection
Collection of Sp instances.
SppCollection
Bases: UcInstanceCollection[SppInstance]
Lightweight SP collection utilities.
from_random(n_positions: int, n_targets: int, density: float = 0.2, num_instances: int = 1, seed: int | None = None) -> SppCollection
classmethod
Generate a collection of random SP instances.
from_json_file(path: str, *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from JSON file.
Args: path: Path to JSON file. max_vert_angle: Maximum vertical viewing angle (degrees). min_vert_angle: Minimum vertical viewing angle (degrees). max_radius: Maximum sensor range. half_horizontal_angle: Half of horizontal field of view (degrees). lidar_wall_offset: Distance from wall endpoints when generating lidars. min_coverage: Required minimum coverage per target. budget: Optional total cost budget. max_positions: Optional cap on selected positions. sensor_reduction: "none" (default), "drop" to remove redundant sensors, "fix" to keep them but mark as fixed on/off.
Returns:
| Type | Description |
|---|---|
SpCollection with one instance from the JSON file.
|
|
from_json_obj(problem_dict: dict[str, Any], *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from an in-memory JSON object.
from_json_str(json_string: str, *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from JSON string payload.