# Example for using exclusion constraints in discrete searchspaces This examples shows how an exclusion constraint can be created for a discrete searchspace. This can be used if some parameter values are incompatible with values of another parameter. This example assumes some basic familiarity with using BayBE. We thus refer to [`campaign`](./../Basics/campaign.md) for a basic example. ## Necessary imports for this example ```python import numpy as np ``` ```python from baybe import Campaign from baybe.constraints import ( DiscreteExcludeConstraint, SubSelectionCondition, ThresholdCondition, ) from baybe.objectives import SingleTargetObjective from baybe.parameters import ( CategoricalParameter, NumericalDiscreteParameter, SubstanceParameter, ) from baybe.searchspace import SearchSpace from baybe.targets import NumericalTarget from baybe.utils.dataframe import add_fake_results ``` ## Experiment setup We begin by setting up some parameters for our experiments. ```python dict_solvent = { "water": "O", "C1": "C", "C2": "CC", "C3": "CCC", "C4": "CCCC", "C5": "CCCCC", "c6": "c1ccccc1", "C6": "CCCCCC", } solvent = SubstanceParameter(name="Solv", data=dict_solvent, encoding="RDKIT") speed = CategoricalParameter( name="Speed", values=["very slow", "slow", "normal", "fast", "very fast"], encoding="INT", ) temperature = NumericalDiscreteParameter( name="Temp", values=list(np.linspace(100, 200, 15)), tolerance=0.4 ) pressure = NumericalDiscreteParameter( name="Pressure", values=[1, 2, 5, 10], tolerance=0.4 ) ``` ```python parameters = [solvent, speed, temperature, pressure] ``` ## Creating the constraint This constraint simulates a situation where solvents `C2` and `C4` are not compatible with temperatures larger than 151 and should thus be excluded. ```python constraint_1 = DiscreteExcludeConstraint( parameters=["Temp", "Solv"], combiner="AND", conditions=[ ThresholdCondition(threshold=151, operator=">"), SubSelectionCondition(selection=["C4", "C2"]), ], ) ``` This constraint simulates a situation where solvents `C5` and `C6` are not compatible with pressures larger than 5 and should thus be excluded. ```python constraint_2 = DiscreteExcludeConstraint( parameters=["Pressure", "Solv"], combiner="AND", conditions=[ ThresholdCondition(threshold=5, operator=">"), SubSelectionCondition(selection=["C5", "C6"]), ], ) ``` This constraint simulates a situation where pressures below 3 should never be combined with temperatures above 120. ```python constraint_3 = DiscreteExcludeConstraint( parameters=["Pressure", "Temp"], combiner="AND", conditions=[ ThresholdCondition(threshold=3.0, operator="<"), ThresholdCondition(threshold=120.0, operator=">"), ], ) ``` ## Creating the searchspace and the objective We now create the searchspace using the previously defined constraints. ```python searchspace = SearchSpace.from_product( parameters=parameters, constraints=[constraint_1, constraint_2, constraint_3] ) ``` [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator [08:37:21] DEPRECATION WARNING: please use MorganGenerator ```python objective = SingleTargetObjective(target=NumericalTarget(name="Target_1", mode="MAX")) ``` ```python ### Creating and printing the campaign campaign = Campaign(searchspace=searchspace, objective=objective) print(campaign) ``` Campaign Meta Data Batches Done: 0 Fits Done: 0 Search Space Search Space Type: DISCRETE Discrete Search Space Discrete Parameters Name Type Num_Values Encoding 0 Solv SubstanceParameter 8 SubstanceEncoding.RDKIT 1 Speed CategoricalParameter 5 CategoricalEncoding.INT 2 Temp NumericalDiscreteParameter 15 None 3 Pressure NumericalDiscreteParameter 4 None Experimental Representation Solv Speed Temp Pressure 0 water very slow 100.000000 1.0 1 water very slow 100.000000 2.0 2 water very slow 100.000000 5.0 ... ... ... ... ... 1147 C6 very fast 185.714286 5.0 1148 C6 very fast 192.857143 5.0 1149 C6 very fast 200.000000 5.0 [1150 rows x 4 columns] Metadata: was_recommended: 0/1150 was_measured: 0/1150 dont_recommend: 0/1150 Constraints Type Affected_Parameters 0 DiscreteExcludeConstraint [Temp, Solv] 1 DiscreteExcludeConstraint [Pressure, Solv] 2 DiscreteExcludeConstraint [Pressure, Temp] Computational Representation Solv_RDKIT_MaxAbsEStateIndex Solv_RDKIT_MaxPartialCharge ... Temp Pressure 0 0.000000 -0.411510 ... 100.000000 1.0 1 0.000000 -0.411510 ... 100.000000 2.0 2 0.000000 -0.411510 ... 100.000000 5.0 ... ... ... ... ... ... 1147 2.231806 -0.053579 ... 185.714286 5.0 1148 2.231806 -0.053579 ... 192.857143 5.0 1149 2.231806 -0.053579 ... 200.000000 5.0 [1150 rows x 9 columns] Objective Type: SingleTargetObjective Targets  Type Name Mode Lower_Bound Upper_Bound Transformation 0 NumericalTarget Target_1 MAX -inf inf None TwoPhaseMetaRecommender(initial_recommender=RandomRecommender(allow_repeated_recomm endations=False, allow_recommending_already_measured=True), recommender=BotorchRecommender(allow_repeated_recommendations=False, allow_recommending_already_measured=True, surrogate_model=GaussianProcessSurrogate(kernel_factory=DefaultKernelFactory(), _model=None), acquisition_function=qLogExpectedImprovement(), _botorch_acqf=None, acquisition_function_cls=None, sequential_continuous=False, hybrid_sampler=None, sampling_percentage=1.0), switch_after=1) ## Manual verification of the constraints The following loop performs some iterations and manually verifies the given constraints. ```python N_ITERATIONS = 3 for kIter in range(N_ITERATIONS): print(f"\n\n#### ITERATION {kIter+1} ####") print("## ASSERTS ##") print( "Number of entries with either Solvents C2 or C4 and a temperature above 151: ", ( campaign.searchspace.discrete.exp_rep["Temp"].apply(lambda x: x > 151) & campaign.searchspace.discrete.exp_rep["Solv"].apply( lambda x: x in ["C2", "C4"] ) ).sum(), ) print( "Number of entries with either Solvents C5 or C6 and a pressure above 5: ", ( campaign.searchspace.discrete.exp_rep["Pressure"].apply(lambda x: x > 5) & campaign.searchspace.discrete.exp_rep["Solv"].apply( lambda x: x in ["C5", "C6"] ) ).sum(), ) print( "Number of entries with pressure below 3 and temperature above 120: ", ( campaign.searchspace.discrete.exp_rep["Pressure"].apply(lambda x: x < 3) & campaign.searchspace.discrete.exp_rep["Temp"].apply(lambda x: x > 120) ).sum(), ) rec = campaign.recommend(batch_size=5) add_fake_results(rec, campaign.targets) campaign.add_measurements(rec) ``` #### ITERATION 1 #### ## ASSERTS ## Number of entries with either Solvents C2 or C4 and a temperature above 151: 0 Number of entries with either Solvents C5 or C6 and a pressure above 5: 0 Number of entries with pressure below 3 and temperature above 120: 0 #### ITERATION 2 #### ## ASSERTS ## Number of entries with either Solvents C2 or C4 and a temperature above 151: 0 Number of entries with either Solvents C5 or C6 and a pressure above 5: 0 Number of entries with pressure below 3 and temperature above 120: 0 #### ITERATION 3 #### ## ASSERTS ## Number of entries with either Solvents C2 or C4 and a temperature above 151: 0 Number of entries with either Solvents C5 or C6 and a pressure above 5: 0 Number of entries with pressure below 3 and temperature above 120: 0