Skip to content

TwoLevelTree and StrategicScenario #89

Description

@JulStraus

Problem statement

The current version for strategic scenarios results in a problem when we have different types of TimeStructures in the TreeNodes. The problem is most likely related to the constructor for StrategicScenario, and there specifically coupled to the created Tuple as it is not a NTuple.

Consider the following structure:

day = SimpleTimes(24, 1)    # A single day with hourly resolution
week = SimpleTimes(168, 1)  # A week with hourly resolution
scen = OperationalScenarios(2, [day, week], [7, 1]/8)
repr = RepresentativePeriods(4, 8760, scen)

ts = TwoLevelTree(
    TreeNode(5, repr, [0.7, 0.05, 0.1, 0.15], [
        TreeNode(5, repr, TreeNode(5, repr, TreeNode(5, week))),
        TreeNode(2, week, TreeNode(8, week, TreeNode(5, week))),
        TreeNode(4, scen, [
            TreeNode(6, week, TreeNode(5, week)),
            TreeNode(6, week, 2, TreeNode(5, week))
        ]
        ),
        TreeNode(5, repr, 2, TreeNode(8, repr, TreeNode(5, week)))
    ]),
; op_per_strat=8760.0)

In this situation, we have a weird subtype structure for the StrategicScenario, that is, the NTuple is not possible to be defined equally. I think the problem is that that typeof(ts) = TwoLevelTree{Int64, Int64, TimeStruct.StratNode{Int64, Int64, OP} where OP<:TimeStructure{Int64}}, and hence, typeof(strategic_scenarios(ts)) = TimeStruct.StratScens{Int64, Int64, TimeStruct.StratNode{Int64, Int64, OP} where OP<:TimeStructure{Int64}}. Specifically, there where is problematic as it won't define an NTuple, but a Tuple.

The problem is most likely introduced through #83. I will try to investigate what type of fixes can solve the issue, but it is a bit of a problem regarding the parametric composite type introduced in #83 for StrategicScenario.

An alternative would be remove the composite type or change it, but as far as I recall this would lead to other unintended consequences as it was initially included to have the equalities working as highlighted in #83. I will investigate it a bit in the coming days. This is just for your information @hellemo and @trulsf.

Activity

  1. self-assigned this
    on Feb 26, 2026
  2. trulsf commented on Feb 26, 2026

    @trulsf
    Member

    I played around a bit with some solutions, and this one seemed to work ok for me. Define the nodes of the StrategicScenario as an invariant type (removing the <:):

    struct StrategicScenario{S,T,N,OP<:AbstractTreeNode{S,T}} <: AbstractStrategicScenario{T}
        scen::Int64
        probability::Float64
        nodes::NTuple{N,OP}
        op_per_strat::Float64
    end

    Then use explicit type parameters in the StrategicScenario construction:

    function StrategicScenario(
        scs::StratScens{S,T,OP},
        scen::Int,
    ) where {S,T,OP}
        node = get_leaf(scs.ts, scen)
        prob = probability_branch(node)
        N = _strat_per(node)
        nodes = Vector{OP}(undef, N)
        for sp in N:-1:1
            nodes[sp] = node
            node = _parent(node)
        end
        return StrategicScenario{S,T,N,OP}(scen, prob, Tuple(nodes), scs.ts.op_per_strat)
    end
  3. JulStraus commented on Feb 26, 2026

    @JulStraus
    CollaboratorAuthor

    I played with my weird example and it seems to work. I can create a PR related to it and add tests for it. Thanks for the fast solution.

  4. JulStraus commented on Feb 27, 2026

    @JulStraus
    CollaboratorAuthor

    Fixed through #90

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions