reasoning with constraints branch-and-bound search here we specialize the branch-and-bound algorithm (section on page cspsoft py -(continued from display import displayablevisualize import math class df_branch_and_bound_opt(displayable)"""returns branch and bound searcher for problem an optimal assignment with cost less than bound can be found by calling search(""def __init__(selfcspbound=math inf)"""creates searcher than can be used with search(to find an optimal path bound gives the initial bound by default this is infinite meaning there is no initial pruning due to depth bound ""super(__init__(self csp csp self best_asst none self bound bound def optimize(self)"""returns an optimal solution to problem with cost less than bound returns none if there is no solution with cost less than bound ""self num_expanded= self cbsearch({} self csp constraintsself display( ,"number of paths expanded:",self num_expandedreturn self best_asstself bound def cbsearch(selfasstcostconstraints)"""finds the optimal solution that extends path and is less the bound""self display( ,"cbsearch:",asst,cost,constraintscan_eval [ for in constraints if can_evaluate(asst)rem_cons [ for in constraints if not in can_evalnewcost cost sum( value(asstfor in can_evalself display( ,"evaluaing:",can_eval,"cost:",newcostif newcost self boundself num_expanded + if rem_cons==[]self best_asst asst self bound newcost self display( ,"new best assignment:",asst,cost:",newcostelsevar next(var for var in self csp variables if var not in asstversion june