def test_indexedvar_noindextemplate(self): st_model = CreateConcreteTwoStageScenarioTreeModel(1) st_model.StageVariables['Stage1'].add("x") st_model.StageDerivedVariables['Stage1'].add("y") st_model.NodeVariables['RootNode'].add("z") st_model.NodeDerivedVariables['RootNode'].add("q") st_model.StageCost['Stage1'] = "FirstStageCost" st_model.StageCost['Stage2'] = "SecondStageCost" scenario_tree = ScenarioTree(scenariotreeinstance=st_model) self.assertEqual(len(scenario_tree.stages), 2) self.assertEqual(len(scenario_tree.nodes), 2) self.assertEqual(len(scenario_tree.scenarios), 1) model = ConcreteModel() model.s = Set(initialize=[1, 2, 3]) model.x = Var(model.s) model.y = Var(model.s) model.z = Var(model.s) model.q = Var(model.s) model.FirstStageCost = Expression(expr=0.0) model.SecondStageCost = Expression(expr=0.0) model.obj = Objective(expr=0.0) scenario_tree.linkInInstances({'Scenario1': model}) root = scenario_tree.findRootNode() self.assertEqual(len(root._variable_ids), 12) self.assertEqual(len(root._standard_variable_ids), 6) self.assertEqual(len(root._derived_variable_ids), 6) for name in ("x", "y", "z", "q"): for index in model.s: self.assertEqual((name, index) in root._name_index_to_id, True)
def test_indexedblock_wildcardtemplate(self): st_model = CreateConcreteTwoStageScenarioTreeModel(1) st_model.StageVariables['Stage1'].add("B1[*]") st_model.StageDerivedVariables['Stage1'].add("B2[*]") st_model.NodeVariables['RootNode'].add("B3[*]") st_model.NodeDerivedVariables['RootNode'].add("B4[*]") st_model.StageCost['Stage1'] = "FirstStageCost" st_model.StageCost['Stage2'] = "SecondStageCost" scenario_tree = ScenarioTree(scenariotreeinstance=st_model) self.assertEqual(len(scenario_tree.stages), 2) self.assertEqual(len(scenario_tree.nodes), 2) self.assertEqual(len(scenario_tree.scenarios), 1) model = self._get_block_model() scenario_tree.linkInInstances({'Scenario1': model}) root = scenario_tree.findRootNode() self.assertEqual(len(root._variable_ids), 24) self.assertEqual(len(root._standard_variable_ids), 12) self.assertEqual(len(root._derived_variable_ids), 12) for name in ("B1[1].x", "B1[2].x", "B2[1].x", "B2[2].x", "B3[1].x", "B3[2].x", "B4[1].x", "B4[2].x"): for index in [None]: self.assertEqual((name, index) in root._name_index_to_id, True) for name in ("B1[1].X", "B1[2].X", "B2[1].X", "B2[2].X", "B3[1].X", "B3[2].X", "B4[1].X", "B4[2].X"): for index in model.s: self.assertEqual((name, index) in root._name_index_to_id, True)
def test_singletonvar_wildcardtemplate(self): st_model = CreateConcreteTwoStageScenarioTreeModel(1) st_model.StageVariables['Stage1'].add("x[*]") st_model.StageDerivedVariables['Stage1'].add("y[*]") st_model.NodeVariables['RootNode'].add("z[*]") st_model.NodeDerivedVariables['RootNode'].add("q[*]") st_model.StageCost['Stage1'] = "FirstStageCost" st_model.StageCost['Stage2'] = "SecondStageCost" scenario_tree = ScenarioTree(scenariotreeinstance=st_model) self.assertEqual(len(scenario_tree.stages), 2) self.assertEqual(len(scenario_tree.nodes), 2) self.assertEqual(len(scenario_tree.scenarios), 1) model = ConcreteModel() model.x = Var() model.y = Var() model.z = Var() model.q = Var() model.FirstStageCost = Expression(expr=0.0) model.SecondStageCost = Expression(expr=0.0) model.obj = Objective(expr=0.0) scenario_tree.linkInInstances({'Scenario1': model}) root = scenario_tree.findRootNode() self.assertEqual(len(root._variable_ids), 4) self.assertEqual(len(root._standard_variable_ids), 2) self.assertEqual(len(root._derived_variable_ids), 2) for name in ("x", "y", "z", "q"): for index in [None]: self.assertEqual((name, index) in root._name_index_to_id, True)
def test_singletonblock_noindextemplate(self): st_model = CreateConcreteTwoStageScenarioTreeModel(1) st_model.StageVariables['Stage1'].add("b1") st_model.StageDerivedVariables['Stage1'].add("b2") st_model.NodeVariables['RootNode'].add("b3") st_model.NodeDerivedVariables['RootNode'].add("b4") st_model.StageCost['Stage1'] = "FirstStageCost" st_model.StageCost['Stage2'] = "SecondStageCost" scenario_tree = ScenarioTree(scenariotreeinstance=st_model) self.assertEqual(len(scenario_tree.stages), 2) self.assertEqual(len(scenario_tree.nodes), 2) self.assertEqual(len(scenario_tree.scenarios), 1) model = self._get_block_model() scenario_tree.linkInInstances({'Scenario1': model}) root = scenario_tree.findRootNode() self.assertEqual(len(root._variable_ids), 12) self.assertEqual(len(root._standard_variable_ids), 6) self.assertEqual(len(root._derived_variable_ids), 6) for name in ("b1.x", "b2.x", "b3.x", "b4.x"): for index in [None]: self.assertEqual((name, index) in root._name_index_to_id, True) for name in ("b1.X", "b2.X", "b3.X", "b4.X"): for index in model.s: self.assertEqual((name, index) in root._name_index_to_id, True)
def test_bundles(self): G = networkx.DiGraph() G.add_node("r") for i in range(4): G.add_node("u" + str(i), bundle=i % 2) G.add_edge("r", "u" + str(i)) model = ScenarioTreeModelFromNetworkX(G, edge_probability_attribute=None) self.assertEqual(sorted(list(model.Stages)), sorted(["Stage1", "Stage2"])) self.assertEqual(sorted(list(model.Nodes)), sorted(["r", "u0", "u1", "u2", "u3"])) self.assertEqual(sorted(list(model.Children["r"])), sorted(["u0", "u1", "u2", "u3"])) for i in range(4): self.assertEqual(sorted(list(model.Children["u" + str(i)])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted(["u0", "u1", "u2", "u3"])) self.assertEqual(value(model.ConditionalProbability["r"]), 1.0) for i in range(4): self.assertEqual(value(model.ConditionalProbability["u" + str(i)]), 0.25) self.assertEqual(model.Bundling.value, True) self.assertEqual(list(model.Bundles), [0, 1]) for k, bundle_name in enumerate(model.Bundles): self.assertEqual(list(model.BundleScenarios[bundle_name]), ["u" + str(i) for i in range(4) if i % 2 == k]) model.StageCost["Stage1"] = "c1" model.StageCost["Stage2"] = "c2" model.StageVariables["Stage1"].add("x") ScenarioTree(scenariotreeinstance=model)
def test_two_stage_custom_names(self): G = networkx.DiGraph() G.add_node("R", label="Root") G.add_node("C1", label="Child1", scenario="S1") G.add_edge("R", "C1", probability=0.8) G.add_node("C2", label="Child2", scenario="S2") G.add_edge("R", "C2", probability=0.2) model = ScenarioTreeModelFromNetworkX( G, edge_probability_attribute="probability", node_name_attribute="label", stage_names=["T1", "T2"], scenario_name_attribute="scenario") self.assertEqual(sorted(list(model.Stages)), sorted(["T1", "T2"])) self.assertEqual(sorted(list(model.Nodes)), sorted(["Root", "Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Root"])), sorted(["Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Child1"])), sorted([])) self.assertEqual(sorted(list(model.Children["Child2"])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted(["S1", "S2"])) self.assertEqual(value(model.ConditionalProbability["Root"]), 1.0) self.assertEqual(value(model.ConditionalProbability["Child1"]), 0.8) self.assertEqual(value(model.ConditionalProbability["Child2"]), 0.2) model.StageCost["T1"] = "c1" model.StageCost["T2"] = "c2" model.StageVariables["T1"].add("x") self.assertEqual(model.Bundling.value, False) self.assertEqual(list(model.Bundles), []) self.assertEqual(len(model.BundleScenarios), 0) ScenarioTree(scenariotreeinstance=model)
def test_two_stage(self): G = networkx.DiGraph() G.add_node("Root") G.add_node("Child1") G.add_edge("Root", "Child1", weight=0.8) G.add_node("Child2") G.add_edge("Root", "Child2", weight=0.2) model = ScenarioTreeModelFromNetworkX(G) self.assertEqual(sorted(list(model.Stages)), sorted(["Stage1", "Stage2"])) self.assertEqual(sorted(list(model.Nodes)), sorted(["Root", "Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Root"])), sorted(["Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Child1"])), sorted([])) self.assertEqual(sorted(list(model.Children["Child2"])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted(["Child1", "Child2"])) self.assertEqual(value(model.ConditionalProbability["Root"]), 1.0) self.assertEqual(value(model.ConditionalProbability["Child1"]), 0.8) self.assertEqual(value(model.ConditionalProbability["Child2"]), 0.2) model.StageCost["Stage1"] = "c1" model.StageCost["Stage2"] = "c2" model.StageVariables["Stage1"].add("x") self.assertEqual(model.Bundling.value, False) self.assertEqual(list(model.Bundles), []) self.assertEqual(len(model.BundleScenarios), 0) ScenarioTree(scenariotreeinstance=model)
def test_two_stage_more_node_attributes(self): G = networkx.DiGraph() G.add_node("Root", cost="c1", variables=["x"], derived_variables=["y"]) G.add_node("Child1", cost="c2", variables=["q"], derived_variables=["z"]) G.add_edge("Root", "Child1", weight=0.8) G.add_node("Child2", cost="c2", variables=["q"], derived_variables=["z"]) G.add_edge("Root", "Child2", weight=0.2) model = ScenarioTreeModelFromNetworkX(G) self.assertEqual(sorted(list(model.Stages)), sorted(["Stage1", "Stage2"])) self.assertEqual(sorted(list(model.Nodes)), sorted(["Root", "Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Root"])), sorted(["Child1", "Child2"])) self.assertEqual(sorted(list(model.Children["Child1"])), sorted([])) self.assertEqual(sorted(list(model.Children["Child2"])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted(["Child1", "Child2"])) self.assertEqual(value(model.ConditionalProbability["Root"]), 1.0) self.assertEqual(value(model.ConditionalProbability["Child1"]), 0.8) self.assertEqual(value(model.ConditionalProbability["Child2"]), 0.2) self.assertEqual(model.StageCost["Stage1"].value, None) self.assertEqual(list(model.StageVariables["Stage1"]), []) self.assertEqual(list(model.StageDerivedVariables["Stage1"]), []) self.assertEqual(model.NodeCost["Root"].value, "c1") self.assertEqual(list(model.NodeVariables["Root"]), ["x"]) self.assertEqual(list(model.NodeDerivedVariables["Root"]), ["y"]) self.assertEqual(model.StageCost["Stage2"].value, None) self.assertEqual(list(model.StageVariables["Stage2"]), []) self.assertEqual(list(model.StageDerivedVariables["Stage2"]), []) self.assertEqual(model.NodeCost["Child1"].value, "c2") self.assertEqual(list(model.NodeVariables["Child1"]), ["q"]) self.assertEqual(list(model.NodeDerivedVariables["Child1"]), ["z"]) self.assertEqual(model.NodeCost["Child2"].value, "c2") self.assertEqual(list(model.NodeVariables["Child2"]), ["q"]) self.assertEqual(list(model.NodeDerivedVariables["Child2"]), ["z"]) self.assertEqual(model.Bundling.value, False) self.assertEqual(list(model.Bundles), []) self.assertEqual(len(model.BundleScenarios), 0) ScenarioTree(scenariotreeinstance=model)
def test_multi_stage(self): G = networkx.balanced_tree(3, 2, networkx.DiGraph()) model = ScenarioTreeModelFromNetworkX(G, edge_probability_attribute=None) self.assertEqual(sorted(list(model.Stages)), sorted(["Stage1", "Stage2", "Stage3"])) self.assertEqual(sorted(list(model.Nodes)), sorted([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])) self.assertEqual(sorted(list(model.Children[0])), sorted([1, 2, 3])) self.assertEqual(sorted(list(model.Children[1])), sorted([4, 5, 6])) self.assertEqual(sorted(list(model.Children[2])), sorted([7, 8, 9])) self.assertEqual(sorted(list(model.Children[3])), sorted([10, 11, 12])) self.assertEqual(sorted(list(model.Children[4])), sorted([])) self.assertEqual(sorted(list(model.Children[5])), sorted([])) self.assertEqual(sorted(list(model.Children[6])), sorted([])) self.assertEqual(sorted(list(model.Children[7])), sorted([])) self.assertEqual(sorted(list(model.Children[8])), sorted([])) self.assertEqual(sorted(list(model.Children[9])), sorted([])) self.assertEqual(sorted(list(model.Children[10])), sorted([])) self.assertEqual(sorted(list(model.Children[11])), sorted([])) self.assertEqual(sorted(list(model.Children[12])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted([4, 5, 6, 7, 8, 9, 10, 11, 12])) self.assertEqual(value(model.ConditionalProbability[0]), 1.0) self.assertAlmostEqual(value(model.ConditionalProbability[1]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[2]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[3]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[4]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[5]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[6]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[7]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[8]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[9]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[10]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[11]), 1.0 / 3) self.assertAlmostEqual(value(model.ConditionalProbability[12]), 1.0 / 3) model.StageCost["Stage1"] = "c1" model.StageCost["Stage2"] = "c2" model.StageCost["Stage3"] = "c3" model.StageVariables["Stage1"].add("x") model.StageVariables["Stage2"].add("y") model.StageVariables["Stage3"].add("y") self.assertEqual(model.Bundling.value, False) self.assertEqual(list(model.Bundles), []) self.assertEqual(len(model.BundleScenarios), 0) ScenarioTree(scenariotreeinstance=model)
def test_unbalanced(self): G = networkx.DiGraph() G.add_node("R") G.add_node("0") G.add_node("1") G.add_edge("R", "0") G.add_edge("R", "1") G.add_node("00") G.add_node("01") G.add_edge("0", "00") G.add_edge("0", "01") model = ScenarioTreeModelFromNetworkX(G, edge_probability_attribute=None) self.assertEqual(sorted(list(model.Stages)), sorted(["Stage1", "Stage2", "Stage3"])) self.assertEqual(sorted(list(model.Nodes)), sorted(["R", "0", "1", "00", "01"])) self.assertEqual(sorted(list(model.Children["R"])), sorted(["0", "1"])) self.assertEqual(sorted(list(model.Children["0"])), sorted(["00", "01"])) self.assertEqual(sorted(list(model.Children["1"])), sorted([])) self.assertEqual(sorted(list(model.Children["00"])), sorted([])) self.assertEqual(sorted(list(model.Children["01"])), sorted([])) self.assertEqual(sorted(list(model.Scenarios)), sorted(["00", "01", "1"])) self.assertEqual(value(model.ConditionalProbability["R"]), 1.0) self.assertEqual(value(model.ConditionalProbability["0"]), 0.5) self.assertEqual(value(model.ConditionalProbability["1"]), 0.5) self.assertEqual(value(model.ConditionalProbability["00"]), 0.5) self.assertEqual(value(model.ConditionalProbability["01"]), 0.5) model.StageCost["Stage1"] = "c1" model.StageCost["Stage2"] = "c2" model.StageCost["Stage3"] = "c3" model.StageVariables["Stage1"].add("x") model.StageVariables["Stage2"].add("x") self.assertEqual(model.Bundling.value, False) self.assertEqual(list(model.Bundles), []) self.assertEqual(len(model.BundleScenarios), 0) ScenarioTree(scenariotreeinstance=model)
def generate_scenario_tree(self, downsample_fraction=1.0, include_scenarios=None, bundles=None, random_bundles=None, random_seed=None, verbose=True): scenario_tree_model = self._scenario_tree_model if scenario_tree_model is not None: if has_networkx and \ isinstance(scenario_tree_model, networkx.DiGraph): scenario_tree_model = \ ScenarioTreeModelFromNetworkX(scenario_tree_model) else: assert isinstance(scenario_tree_model, (_BlockData, Block)), \ str(scenario_tree_model)+" "+str(type(scenario_tree_model)) if bundles is not None: if isinstance(bundles, six.string_types): if scenario_tree_model is None: raise ValueError("A bundles file can not be used when the " "scenario tree input was not a Pyomo " "model or ScenarioStructure.dat file.") logger.debug("attempting to locate bundle file for input: %s" % (bundles)) # we interpret the scenario bundle specification in one of # two ways. if the supplied name is a file, it is used # directly. otherwise, it is interpreted as the root of a # file with a .dat suffix to be found in the instance # directory. orig_input = bundles if not bundles.endswith(".dat"): bundles = bundles + ".dat" bundles = os.path.expanduser(bundles) if not os.path.exists(bundles): if self.data_directory() is None: raise ValueError( "Could not locate bundle .dat file from input " "'%s'. Path does not exist and there is no data " "directory to search in." % (orig_input)) bundles = os.path.join(self.data_directory(), bundles) if not os.path.exists(bundles): raise ValueError("Could not locate bundle .dat file " "from input '%s' as absolute path or " "relative to data directory: %s" % (orig_input, self.data_directory())) if verbose: print("Scenario tree bundle specification filename=%s" % (bundles)) scenario_tree_model = scenario_tree_model.clone() scenario_tree_model.Bundling = True scenario_tree_model.Bundling._constructed = False scenario_tree_model.Bundling._data.clear() scenario_tree_model.Bundles.clear() scenario_tree_model.Bundles._constructed = False scenario_tree_model.Bundles._data.clear() scenario_tree_model.BundleScenarios.clear() scenario_tree_model.BundleScenarios._constructed = False scenario_tree_model.BundleScenarios._data.clear() scenario_tree_model.load(bundles) # # construct the scenario tree # if scenario_tree_model is not None: scenario_tree = ScenarioTree( scenariotreeinstance=scenario_tree_model, scenariobundlelist=include_scenarios) else: assert self._scenario_tree is not None if include_scenarios is None: scenario_tree = copy.deepcopy(self._scenario_tree) else: # note: any bundles will be lost if self._scenario_tree.contains_bundles(): raise ValueError("Can not compress a scenario tree that " "contains bundles") scenario_tree = self._scenario_tree.make_compressed( include_scenarios, normalize=True) # compress/down-sample the scenario tree, if requested if (downsample_fraction is not None) and \ (downsample_fraction < 1.0): scenario_tree.downsample(downsample_fraction, random_seed, verbose) # # create bundles from a dict, if requested # if bundles is not None: if not isinstance(bundles, six.string_types): if verbose: print("Adding bundles to scenario tree from " "user-specified dict") if scenario_tree.contains_bundles(): if verbose: print("Scenario tree already contains bundles. " "All existing bundles will be removed.") for bundle in list(scenario_tree.bundles): scenario_tree.remove_bundle(bundle.name) for bundle_name in bundles: scenario_tree.add_bundle(bundle_name, bundles[bundle_name]) # # create random bundles, if requested # if (random_bundles is not None) and \ (random_bundles > 0): if bundles is not None: raise ValueError("Cannot specify both random " "bundles and a bundles specification") num_scenarios = len(scenario_tree._scenarios) if random_bundles > num_scenarios: raise ValueError("Cannot create more random bundles " "than there are scenarios!") if verbose: print("Creating " + str(random_bundles) + " random bundles using seed=" + str(random_seed)) scenario_tree.create_random_bundles(random_bundles, random_seed) scenario_tree._scenario_instance_factory = self return scenario_tree