# ___________________________________________________________________________ # # Pyomo: Python Optimization Modeling Objects # Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC # Under the terms of Contract DE-NA0003525 with National Technology and # Engineering Solutions of Sandia, LLC, the U.S. Government retains certain # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ from six import iteritems # the intent of this file is to provide a collection of generator # (iterables) functions, which embody certain highly repeated patterns # of nested iteration in PySP. these generators should allow for # simplification of the code base, and should generally improve # maintainability. # iterates over each stage (minus possibly the last, depending on the # keyword arguments), each tree node in each stage, each variable in # each tree node, and each component of each variable. returns a # six-tuple, including: # - the stage # - the tree node # - the variable name # - the index of the variable # - a sequence of (_VarData, probability) pairs for each scenario # instance at this node. # - a boolean indicating whether the variable/index is fixed in all # scenario instance. # NOTE: We don't actually check for agreement, but we should. # - a boolean indicating whether the variable/index is stale in all # scenario instances. def scenario_tree_node_variables_generator(scenario_tree, includeDerivedVariables=True, includeLastStage=True, sort=False): if includeLastStage is False: stages_to_iterate = scenario_tree._stages[:-1] else: stages_to_iterate = scenario_tree._stages for stage in stages_to_iterate: tree_nodes = stage._tree_nodes if sort: tree_nodes = sorted(tree_nodes, key=lambda n: n.name) for tree_node in tree_nodes: variter = iteritems(tree_node._variable_datas) if sort: variter = sorted(variter, key=lambda x: x[0]) for variable_id, variable_datas in variter: if (not includeDerivedVariables) and \ (variable_id in tree_node._derived_variable_ids): continue # implicit assumption is that if a variable value is # fixed / stale in one scenario, it is fixed / stale # in all scenarios is_stale = False is_fixed = False instance_fixed_count = 0 assert len(variable_datas) for var_data, scenario_probability in variable_datas: if var_data.stale is True: is_stale = True if var_data.fixed is True: instance_fixed_count += 1 is_fixed = True assert is_fixed == tree_node.is_variable_fixed(variable_id) if ((instance_fixed_count > 0) and \ (instance_fixed_count < len(tree_node._scenarios))): variable_name, index = tree_node._variable_ids[variable_id] raise RuntimeError("Variable="+variable_name+str(index)+" is " "fixed in "+str(instance_fixed_count)+" " "scenarios, which is less than the number " "of scenarios at tree node="+tree_node._name) yield (stage, tree_node, variable_id, variable_datas, is_fixed, is_stale) def scenario_tree_node_variables_generator_noinstances(scenario_tree, includeDerivedVariables=True, includeLastStage=True, sort=False): if includeLastStage is False: stages_to_iterate = scenario_tree._stages[:-1] else: stages_to_iterate = scenario_tree._stages for stage in stages_to_iterate: tree_nodes = stage._tree_nodes if sort: tree_nodes = sorted(tree_nodes, key=lambda n: n.name) for tree_node in tree_nodes: variter = tree_node._variable_ids if sort: variter = sorted(variter) for variable_id in variter: if (not includeDerivedVariables) and \ (variable_id in tree_node._derived_variable_ids): continue variable_values = [] is_fixed = tree_node.is_variable_fixed(variable_id) is_stale = False instance_fixed_count = 0 for scenario in tree_node._scenarios: if scenario.is_variable_stale(tree_node, variable_id): is_stale = True if scenario.is_variable_fixed(tree_node, variable_id): instance_fixed_count += 1 variable_values.append((scenario._x[tree_node._name][variable_id], scenario._probability)) if ((instance_fixed_count > 0) and \ (instance_fixed_count < len(tree_node._scenarios))): variable_name, index = tree_node._variable_ids[variable_id] raise RuntimeError("Variable="+variable_name+str(index)+" is " "fixed in "+str(instance_fixed_count)+" " "scenarios, which is less than the number " "of scenarios at tree node="+tree_node._name) yield (stage, tree_node, variable_id, variable_values, is_fixed, is_stale)