diff --git a/src/topupopt/problems/esipp/model.py b/src/topupopt/problems/esipp/model.py index 1b37e1640920faa213eb7b1e178c9e492fc15d1e..412e5d959cbe1f17a66b5b1723cbe454c387388a 100644 --- a/src/topupopt/problems/esipp/model.py +++ b/src/topupopt/problems/esipp/model.py @@ -92,6 +92,10 @@ def create_model( model.set_G, within=model.set_L ) # should inherently exclude import nodes + model.set_L_max_out_g = pyo.Set( + model.set_G, within=model.set_L + ) # should inherently exclude export nodes + # ************************************************************************* # ************************************************************************* @@ -2677,33 +2681,25 @@ def create_model( return pyo.Constraint.Skip # max number of directed incoming arcs - n_max_dir_in = sum( sum( 1 for j in m.set_J[(g, l_line, l)] if j not in m.set_J_und[(g, l_line, l)] ) # directed - for l_line in m.set_L[g] - if l_line != l - if l_line not in m.set_L_imp[g] + for l_line in m.set_L[g] # for every node + if l_line != l # cannot be the same node + # if l_line not in m.set_L_imp[g] # why? if (g, l_line, l) in m.set_J ) # check the maximum number of incoming arcs - if n_max_dir_in <= 1: # there can only be one incoming arc at most: redundant constraint - return pyo.Constraint.Skip - else: # more than one incoming arc is possible - # ***************************************************************** - + # number of (new) incoming directed arcs in a group - - # ***************************************************************** - b_max_in_gl = 0 # the big m @@ -2765,6 +2761,7 @@ def create_model( if j_dot not in m.set_J_und[(g, l_circ, l)] # directed if j_dot not in m.set_J_int[(g, l_circ, l)] # not interfaced if j_dot not in m.set_J_col[(g, l_circ, l)] # individual + if j_dot not in m.set_J_pre[(g, l_circ, l)] # new if j_dot not in m.set_J_mdt[(g, l_circ, l)] # optional ) if (g, l_circ, l) in m.set_J @@ -2918,19 +2915,255 @@ def create_model( return temp_constr model.constr_max_incoming_directed_arcs = pyo.Constraint( - model.set_GL_not_exp_imp, rule=rule_constr_max_incoming_directed_arcs + model.set_GL, rule=rule_constr_max_incoming_directed_arcs ) # ************************************************************************* - # def rule_constr_max_outgoing_directed_arcs(m, g, l): + def rule_constr_max_outgoing_directed_arcs(m, g, l): + # check if the node is not among those subject to a limited number of outgoing arcs + if l not in m.set_L_max_out_g[g]: + # it is not, skip this constraint + return pyo.Constraint.Skip - # pass + # max number of directed outgoing arcs + n_max_dir_out = sum( + sum( + 1 + for j in m.set_J[(g, l, l_line)] + if j not in m.set_J_und[(g, l, l_line)] + ) # directed + for l_line in m.set_L[g] + if l_line != l + # if l_line not in m.set_L_exp[g] # cannot be an export: why? + if (g, l, l_line) in m.set_J + ) + + # check the maximum number of incoming arcs + if n_max_dir_out <= 1: + # there can only be one outgoing arc at most: redundant constraint + # TODO: consider this condition when defining the set + return pyo.Constraint.Skip + else: # more than one outgoing arc is possible - # model.constr_max_outgoing_directed_arcs = pyo.Constraint( - # model.set_GL_not_exp_imp, - # rule=rule_constr_max_outgoing_directed_arcs - # ) + # number of (new) incoming directed arcs in a group + b_max_out_gl = 0 + + # the big m + M_gl = n_max_dir_out - 1 # has to be positive since n_max_dir_out > 1 + # TODO: put parenthesis to avoid funny results + temp_constr = ( + sum( + # ********************************************************* + # interfaced groups + sum( + sum( + 1 + for j in m.set_J_col[(g, l, l_circ)] # part of group + if j not in m.set_J_und[(g, l, l_circ)] # directed + if (g, l, l_circ, j) in m.set_GLLJ_col_t[t] + ) + * m.var_xi_arc_inv_t[t] # in t + for t in m.set_T_int + ) + + + # ********************************************************* + # optional non-interfaced groups + sum( + sum( + sum( + 1 + for j in m.set_J_col[(g, l, l_circ)] # part of group + if j not in m.set_J_und[(g, l, l_circ)] # directed + if (g, l, l_circ, j) in m.set_GLLJ_col_t[t] + ) + * m.var_delta_arc_inv_th[(t, h)] + for h in m.set_H_t[t] + ) + for t in m.set_T + if t not in m.set_T_mdt # optional + if t not in m.set_T_int # not interfaced + ) + + + # ********************************************************* + # interfaced arcs + (sum( + m.var_xi_arc_inv_gllj[(g, l, l_circ, j_circ)] + for j_circ in m.set_J[(g, l, l_circ)] + if j_circ not in m.set_J_und[(g, l, l_circ)] # directed + if j_circ in m.set_J_int[(g, l, l_circ)] # interfaced + if j_circ not in m.set_J_col[(g, l, l_circ)] # individual + ) + if (g, l, l_circ) in m.set_J + else 0) + + # ********************************************************* + # optional non-interfaced arcs + (sum( + sum( + m.var_delta_arc_inv_glljh[(g, l, l_circ, j_dot, h_dot)] + for h_dot in m.set_H_gllj[(g, l, l_circ, j_dot)] + ) + for j_dot in m.set_J[(g, l, l_circ)] + if j_dot not in m.set_J_und[(g, l, l_circ)] # directed + if j_dot not in m.set_J_int[(g, l, l_circ)] # not interfaced + if j_dot not in m.set_J_col[(g, l, l_circ)] # individual + if j_dot not in m.set_J_pre[(g, l, l_circ)] # new + if j_dot not in m.set_J_mdt[(g, l, l_circ)] # optional + ) + if (g, l, l_circ) in m.set_J + else 0) + + # ********************************************************* + # preexisting directed arcs + (sum( + 1 + for j_pre_dir in m.set_J_pre[(g, l, l_circ)] # preexisting + if j_pre_dir not in m.set_J_und[(g, l, l_circ)] # directed + ) + if (g, l, l_circ) in m.set_J_pre + else 0) + + # ********************************************************* + # mandatory directed arcs + (sum( + 1 + for j_mdt_dir in m.set_J_mdt[(g, l, l_circ)] + if j_mdt_dir not in m.set_J_und[(g, l, l_circ)] # directed + ) + if (g, l, l_circ) in m.set_J_mdt + else 0) + # ********************************************************* + for l_circ in m.set_L[g] + if l_circ not in m.set_L_imp[g] + if l_circ != l + ) + <= 1 # + + # TODO: what is below has copy&pasted, must be completely revised + # M_gl*sum( + # # ********************************************************* + # # outgoing arcs in interfaced groups, nominal direction + # sum(sum(1 + # for j in m.set_J_col[(g,l,l_diamond)] + # #if j in m.set_J_int[(g,l,l_diamond)] + # if (g,l,l_diamond,j) in m.set_GLLJ_col_t[t] + # )*m.var_xi_arc_inv_t[t] + # for t in m.set_T_int + # ) if (g,l,l_diamond) in m.set_J_col else 0 + # + + # # outgoing arcs in interfaced groups, reverse direction + # sum(sum(1 + # for j in m.set_J_col[(g,l_diamond,l)] + # #if j in m.set_J_int[(g,l_diamond,l)] + # if j in m.set_J_und[(g,l_diamond,l)] + # if (g,l_diamond,l,j) in m.set_GLLJ_col_t[t] + # )*m.var_xi_arc_inv_t[t] + # for t in m.set_T_int + # ) if (g,l_diamond,l) in m.set_J_col else 0 + # + + # # ********************************************************* + # # TODO: outgoing arcs in non-interfaced optional groups, nominal + # sum(sum(1 + # for j in m.set_J_col[(g,l,l_diamond)] + # #if j in m.set_J_int[(g,l,l_diamond)] + # if (g,l,l_diamond,j) in m.set_GLLJ_col_t[t] + # )*sum( + # m.var_delta_arc_inv_th[(t,h)] + # for h in m.set_H_t[t] + # ) + # for t in m.set_T + # if t not in m.set_T_mdt + # if t not in m.set_T_int + # ) if (g,l,l_diamond) in m.set_J_col else 0 + # + + # # TODO: outgoing arcs in non-interfaced optional groups, reverse + # sum(sum(1 + # for j in m.set_J_col[(g,l_diamond,l)] + # #if j in m.set_J_int[(g,l_diamond,l)] + # if j in m.set_J_und[(g,l_diamond,l)] + # if (g,l_diamond,l,j) in m.set_GLLJ_col_t[t] + # )*sum( + # m.var_delta_arc_inv_th[(t,h)] + # for h in m.set_H_t[t] + # ) + # for t in m.set_T + # if t not in m.set_T_mdt + # if t not in m.set_T_int + # ) if (g,l_diamond,l) in m.set_J_col else 0 + # + + # # ********************************************************* + # # interfaced individual outgoing arcs, nominal direction + # sum(m.var_xi_arc_inv_gllj[(g,l,l_diamond,j)] + # for j in m.set_J_int[(g,l,l_diamond)] # interfaced + # if j not in m.set_J_col[(g,l,l_diamond)] # individual + # ) if (g,l,l_diamond) in m.set_J_int else 0 + # + + # # ********************************************************* + # # interfaced individual undirected arcs, reverse direction + # sum(m.var_xi_arc_inv_gllj[(g,l,l_diamond,j)] + # for j in m.set_J_und[(g,l_diamond,l)] # undirected + # if j in m.set_J_int[(g,l_diamond,l)] # interfaced + # if j not in m.set_J_col[(g,l_diamond,l)] # individual + # ) if (g,l_diamond,l) in m.set_J_und else 0 + # + + # # ********************************************************* + # # outgoing non-interfaced individual optional arcs + # sum( + # sum(m.var_delta_arc_inv_glljh[(g,l,l_diamond,j,h)] + # for h in m.set_H_gllj[(g,l,l_diamond,j)]) + # for j in m.set_J[(g,l,l_diamond)] + # if j not in m.set_J_col[(g,l,l_diamond)] # individual + # if j not in m.set_J_mdt[(g,l,l_diamond)] # optional + # if j not in m.set_J_int[(g,l,l_diamond)] # interfaced + # ) if (g,l,l_diamond) in m.set_J else 0 + # + + # # ********************************************************* + # # individual non-interfaced undirected arcs, reverse dir. + # sum( + # sum(m.var_delta_arc_inv_glljh[(g,l_diamond,l,j,h)] + # for h in m.set_H_gllj[(g,l_diamond,l,j)]) + # for j in m.set_J_und[(g,l_diamond,l)] # undirected + # if j not in m.set_J_col[(g,l_diamond,l)] # individual + # if j not in m.set_J_mdt[(g,l_diamond,l)] # optional + # if j not in m.set_J_int[(g,l_diamond,l)] # interfaced + # ) if (g,l_diamond,l) in m.set_J_und else 0 + # + + # # ********************************************************* + # # preselected outgonig arcs, nominal direction + # len(m.set_J_pre[(g,l,l_diamond)] + # ) if (g,l,l_diamond) in m.set_J_pre else 0 + # + + # # ********************************************************* + # # mandatory outgoing arcs, nominal direction + # len(m.set_J_mdt[(g,l,l_diamond)] + # ) if (g,l,l_diamond) in m.set_J_mdt else 0 + # + + # # ********************************************************* + # # undirected preselected arcs, reverse direction + # sum(1 + # for j in m.set_J_pre[(g,l_diamond,l)] + # if j in m.set_J_und[(g,l_diamond,l)] + # ) if (g,l_diamond,l) in m.set_J_pre else 0 + # + + # # ********************************************************* + # # undirected mandatory arcs, reverse direction + # sum(1 + # for j in m.set_J_mdt[(g,l_diamond,l)] + # if j in m.set_J_und[(g,l_diamond,l)] + # ) if (g,l_diamond,l) in m.set_J_mdt else 0 + # # ********************************************************* + # for l_diamond in m.set_L[g] + # if l_diamond not in m.set_L_imp[g] + # if l_diamond != l + # ) + ) + if type(temp_constr) == bool: + # trivial outcome + return pyo.Constraint.Feasible if temp_constr else pyo.Constraint.Infeasible + else: + # constraint is relevant + return temp_constr + + model.constr_max_outgoing_directed_arcs = pyo.Constraint( + model.set_GL, rule=rule_constr_max_outgoing_directed_arcs + ) # # ************************************************************************* diff --git a/src/topupopt/problems/esipp/network.py b/src/topupopt/problems/esipp/network.py index 1b129d72477d24dda1deb567d69039448ff64159..5e12053e74d96231b39831107d71a0f2dcfb43ea 100644 --- a/src/topupopt/problems/esipp/network.py +++ b/src/topupopt/problems/esipp/network.py @@ -612,21 +612,62 @@ class Network(nx.MultiDiGraph): KEY_ARC_TECH_CAPACITY_INSTANTANEOUS, KEY_ARC_TECH_STATIC_LOSS, ) + + NET_TYPE_HYBRID = 0 + NET_TYPE_TREE = 1 + NET_TYPE_REV_TREE = 2 + + NET_TYPES = ( + NET_TYPE_HYBRID, + NET_TYPE_TREE, + NET_TYPE_REV_TREE + ) - def __init__(self, incoming_graph_data=None, **attr): + def __init__(self, network_type = NET_TYPE_HYBRID, **kwargs): # run base class init routine - nx.MultiDiGraph.__init__(self, incoming_graph_data=incoming_graph_data, **attr) + nx.MultiDiGraph.__init__(self, **kwargs) # identify node types self.identify_node_types() # declare variables for the nodes without directed arc limitations + self.network_type = network_type + + self.nodes_w_in_dir_arc_limitations = dict() + + self.nodes_w_out_dir_arc_limitations = dict() + + # ************************************************************************* + # ************************************************************************* + + def _set_up_node(self, node_key, max_number_in_arcs: int = None, max_number_out_arcs: int = None): + + if self.should_be_tree_network(): + # nodes have to be part of a tree: one incoming arc per node at most + self.nodes_w_in_dir_arc_limitations[node_key] = 1 + elif self.should_be_reverse_tree_network(): + # nodes have to be part of a reverse tree: one outgoing arc per node at most + self.nodes_w_out_dir_arc_limitations[node_key] = 1 + else: + # nodes have no peculiar restrictions or they are defined 1 by 1 + if type(max_number_in_arcs) != type(None): + self.nodes_w_in_dir_arc_limitations[node_key] = max_number_in_arcs + if type(max_number_out_arcs) != type(None): + self.nodes_w_out_dir_arc_limitations[node_key] = max_number_out_arcs - self.nodes_wo_in_dir_arc_limitations = [] + # ************************************************************************* + # ************************************************************************* + + def should_be_tree_network(self) -> bool: + return self.network_type == self.NET_TYPE_TREE - self.nodes_wo_out_dir_arc_limitations = [] + # ************************************************************************* + # ************************************************************************* + + def should_be_reverse_tree_network(self) -> bool: + return self.network_type == self.NET_TYPE_REV_TREE # ************************************************************************* # ************************************************************************* @@ -661,23 +702,25 @@ class Network(nx.MultiDiGraph): # add a new supply/demand node - def add_source_sink_node(self, node_key, base_flow: dict): + def add_source_sink_node(self, node_key, base_flow: dict, **kwargs): node_dict = { self.KEY_NODE_TYPE: self.KEY_NODE_TYPE_SOURCE_SINK, self.KEY_NODE_BASE_FLOW: base_flow, } self.add_node(node_key, **node_dict) + self._set_up_node(node_key, **kwargs) # ************************************************************************* # ************************************************************************* # add a new waypoint node - def add_waypoint_node(self, node_key): + def add_waypoint_node(self, node_key, **kwargs): node_dict = {self.KEY_NODE_TYPE: self.KEY_NODE_TYPE_WAY} self.add_node(node_key, **node_dict) + self._set_up_node(node_key, **kwargs) # ************************************************************************* # ************************************************************************* diff --git a/src/topupopt/problems/esipp/problem.py b/src/topupopt/problems/esipp/problem.py index 7d3c9e55c6c45f4ad585c793a9722dabf77f68bb..206a17c632d64d0cae265b6c929f54811312d389 100644 --- a/src/topupopt/problems/esipp/problem.py +++ b/src/topupopt/problems/esipp/problem.py @@ -1830,22 +1830,14 @@ class InfrastructurePlanningProblem(EnergySystem): } set_L_max_in_g = { - g: tuple( - l - for l in self.networks[g].nodes - if l not in self.networks[g].nodes_wo_in_dir_arc_limitations - ) + g: tuple(self.networks[g].nodes_w_in_dir_arc_limitations.keys()) for g in self.networks.keys() - } + } - # set_L_max_out_g = { - # g: tuple( - # l - # for l in self.networks[g].nodes - # if l not in self.networks[g].nodes_wo_out_dir_arc_limitations - # ) - # for g in self.networks.keys() - # } + set_L_max_out_g = { + g: tuple(self.networks[g].nodes_w_out_dir_arc_limitations.keys()) + for g in self.networks.keys() + } set_GL = tuple((g, l) for g in set_G for l in set_L[g]) @@ -3317,7 +3309,7 @@ class InfrastructurePlanningProblem(EnergySystem): "set_L_imp": set_L_imp, "set_L_exp": set_L_exp, "set_L_max_in_g": set_L_max_in_g, - #'set_L_max_out_g': set_L_max_out_g, + 'set_L_max_out_g': set_L_max_out_g, "set_GL": set_GL, "set_GL_exp": set_GL_exp, "set_GL_imp": set_GL_imp, diff --git a/tests/test_esipp_problem.py b/tests/test_esipp_problem.py index fdb57243d007521d7b57af69a7f415c10f6ed309..8e1b32a28e2b343ca2c3135bf9df304da416d0a3 100644 --- a/tests/test_esipp_problem.py +++ b/tests/test_esipp_problem.py @@ -226,7 +226,7 @@ class TestESIPPProblem: # ipp.instantiate(place_fixed_losses_upstream_if_possible=False) ipp.instantiate(initialise_ancillary_sets=init_aux_sets) - + ipp.instance.pprint() # optimise ipp.optimise( solver_name=solver, @@ -1781,7 +1781,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -1791,7 +1791,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' mynet.add_export_node( node_key=exp_node_key, prices={ @@ -1951,7 +1951,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -1961,7 +1961,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' mynet.add_export_node( node_key=exp_node_key, prices={ @@ -2119,7 +2119,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -2129,7 +2129,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' mynet.add_export_node( node_key=exp_node_key, prices={ @@ -2259,7 +2259,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -2269,7 +2269,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' mynet.add_export_node( node_key=exp_node_key, prices={ @@ -2349,7 +2349,7 @@ class TestESIPPProblem: # no sos, regular time intervals ipp = self.build_solve_ipp( - solver_options={}, + solver_options={},solver='scip', perform_analysis=False, plot_results=False, # True, print_solver_output=False, @@ -3059,7 +3059,7 @@ class TestESIPPProblem: mynet = Network() # import nodes - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -3375,7 +3375,7 @@ class TestESIPPProblem: mynet = Network() # import nodes - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -3638,7 +3638,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' imp_prices = { qpk: ResourcePrice( prices=1.5, @@ -3652,7 +3652,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' exp_prices = { qpk: ResourcePrice( prices=0.5, @@ -3765,7 +3765,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' imp_prices = { qpk: ResourcePrice( prices=0.5, @@ -3779,7 +3779,7 @@ class TestESIPPProblem: ) # export node - exp_node_key = generate_pseudo_unique_key(mynet.nodes()) + exp_node_key = 'thatexpnode' exp_prices = { qpk: ResourcePrice( prices=1.5, @@ -5938,7 +5938,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -6087,7 +6087,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -6240,7 +6240,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -6523,7 +6523,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -6800,7 +6800,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -7084,7 +7084,7 @@ class TestESIPPProblem: mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -7705,11 +7705,10 @@ class TestESIPPProblem: number_periods = 2 # 4 nodes: one import, one export, two supply/demand nodes - mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -7720,7 +7719,7 @@ class TestESIPPProblem: ) # other nodes - node_A = generate_pseudo_unique_key(mynet.nodes()) + node_A = 'A' mynet.add_source_sink_node(node_key=node_A, base_flow={(q, 0): 1.0}) # add arcs @@ -7840,11 +7839,10 @@ class TestESIPPProblem: number_periods = 2 # 4 nodes: one import, one export, two supply/demand nodes - mynet = Network() # import node - imp_node_key = generate_pseudo_unique_key(mynet.nodes()) + imp_node_key = 'thatimpnode' mynet.add_import_node( node_key=imp_node_key, prices={ @@ -7855,7 +7853,7 @@ class TestESIPPProblem: ) # other nodes - node_A = generate_pseudo_unique_key(mynet.nodes()) + node_A = 'A' mynet.add_source_sink_node(node_key=node_A, base_flow={(q, 0): 1.0}) # add arcs @@ -8129,7 +8127,7 @@ class TestESIPPProblem: ) # 2 nodes: one import, one regular - mynet = Network() + mynet = Network(network_type=Network.NET_TYPE_TREE) # import node node_IMP = "thatimpnode" @@ -8223,11 +8221,8 @@ class TestESIPPProblem: max_number_parallel_arcs={}, simplify_problem=True, ) - - print('wowowowow') - ipp.instance.constr_max_incoming_directed_arcs.pprint() assert ipp.has_peak_total_assessments() - assert ipp.results["Problem"][0]["Number of constraints"] == 61 + assert ipp.results["Problem"][0]["Number of constraints"] == 61 assert ipp.results["Problem"][0]["Number of variables"] == 53 assert ipp.results["Problem"][0]["Number of nonzeros"] == 143 @@ -8278,8 +8273,8 @@ class TestESIPPProblem: ) # 2 nodes: one import, one regular - mynet = Network() - + mynet = Network(network_type=Network.NET_TYPE_REV_TREE) + # export node node_EXP = "thatexpnode" mynet.add_export_node( @@ -8309,12 +8304,12 @@ class TestESIPPProblem: base_flow={(q, 0): -1.25}, ) - list_imp_arcs = [ + list_exp_arcs = [ (node_A, node_EXP), # AE (node_B, node_EXP), # BE (node_C, node_EXP), # CE ] - for i, node_pair in enumerate(list_imp_arcs): + for i, node_pair in enumerate(list_exp_arcs): # import arcs: AE, BE, CE new_arc = Arcs( @@ -8372,10 +8367,8 @@ class TestESIPPProblem: max_number_parallel_arcs={}, simplify_problem=True, ) - print('owowowowow') - ipp.instance.constr_max_incoming_directed_arcs.pprint() assert ipp.has_peak_total_assessments() - assert ipp.results["Problem"][0]["Number of constraints"] == 61 + assert ipp.results["Problem"][0]["Number of constraints"] == 61 assert ipp.results["Problem"][0]["Number of variables"] == 53 assert ipp.results["Problem"][0]["Number of nonzeros"] == 143 # @@ -8384,9 +8377,9 @@ class TestESIPPProblem: # validation - # only the IA arc should be installed - true_imp_arcs_selected = [True, False, False] - for node_pair, true_arc_decision in zip(list_imp_arcs, true_imp_arcs_selected): + # only the AE arc should be installed + true_exp_arcs_selected = [True, False, False] + for node_pair, true_arc_decision in zip(list_exp_arcs, true_exp_arcs_selected): assert ( true_arc_decision in ipp.networks["mynet"]