Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''Build_Sustainable.py
- A QUIET Solving Tool problem formulation.
- QUIET = Quetzal User Intelligence Enhancing Technology.
- The XML-like tags used here serve to identify key sections of this
- problem formulation.
- CAPITALIZED constructs are generally present in any problem
- formulation and therefore need to be spelled exactly the way they are.
- Other globals begin with a capital letter but otherwise are lower
- case or camel case.
- '''
- # <METADATA>
- QUIET_VERSION = "0.2"
- PROBLEM_NAME = "Designing buildings for Environmental Sustainability"
- PROBLEM_VERSION = "0.2"
- PROBLEM_AUTHORS = ['A. Krishnamoorthy', "Bum Mook Oh", "Ishan Saksena"]
- PROBLEM_CREATION_DATE = "27-APR-2017"
- PROBLEM_DESC = \
- '''This formulation models sustainable building design uses generic
- Python 3 constructs and has been tested with Python 3.4.
- It is designed to work according to the QUIET tools interface, Version 0.2.
- '''
- # </METADATA>
- # <COMMON_CODE>
- def can_build(s, b_property, amount):
- '''Tests whether we can change the construction factor'''
- brickAmount = 0
- if b_property == 'PeopleServed':
- newCost = brickToPeople(s)
- else:
- newCost = COSTS[b_property]
- try:
- enough_budget = (s.d['budget'] >= newCost)
- if (b_property in bricks(s)):
- brickAmount = s.d['ConstructionMaterial'][b_property]
- return enough_budget and (amount > 0 and amount + brickAmount > 0)
- except (Exception) as e:
- print(e)
- def build(s, b_property, quantity):
- '''Assuming it's legal to make the move, this computes
- the new state resulting from moving the topmost disk
- from the From peg to the To peg.'''
- new_state = s.__copy__() # start with a deep copy.
- d2 = new_state.d # grab the new state's dictionary.
- if (b_property in bricks(s)):
- d2['ConstructionMaterial'][b_property] += quantity
- if b_property == 'PeopleServed':
- d2['budget'] -= brickToPeople(s)
- else:
- d2['budget'] -= COSTS[b_property]
- return new_state # return new state
- def goal_test(s):
- '''If the first two pegs are empty, then s is a goal state.'''
- return not s.d['budget']
- def goal_message(s):
- return "Our building is pretty sustainable"
- class Operator:
- def __init__(self, name, precond, state_transf):
- self.name = name
- self.precond = precond
- self.state_transf = state_transf
- def is_applicable(self, s):
- return self.precond(s)
- def apply(self, s):
- return self.state_transf(s)
- # </COMMON_CODE>
- # <COMMON_DATA>
- # </COMMON_DATA>
- # <STATE>
- class State():
- def __init__(self, d):
- self.d = d
- def __str__(self):
- # Produces a brief textual description of a state.
- d = self.d
- txt = "["
- for k in d.keys():
- if k == 'ConstructionMaterial':
- for brick in self.d[k].keys():
- txt += brick + ': ' + str(self.d[k][brick])
- txt += ", "
- else:
- txt += str(k) + ': ' + str(d[k])
- txt += ", "
- return txt[:-2] + "]"
- def __eq__(self, s2):
- if not (type(self) == type(s2)): return False
- d1 = self.d
- d2 = s2.d
- for k in d1['ConstructionMaterial'].keys():
- if d1['ConstructionMaterial'][k] != d2['ConstructionMaterial'][k]:
- return False
- return (d1['NumberOfPlants'] == d2['NumberOfPlants']) and (d1['PeopleServed'] == d2['PeopleServed'])
- def __hash__(self):
- return (str(self)).__hash__()
- def __copy__(self):
- # Performs an appropriately deep copy of a state,
- # for use by operators in creating new states.
- news = State({})
- self.d
- for k in self.d.keys():
- if k == 'ConstructionMaterial':
- for brick in self.d[k]:
- if 'ConstructionMaterial' not in news.d:
- news.d['ConstructionMaterial'] = {}
- # print(self.d)
- # print()
- # print()
- news.d['ConstructionMaterial'][brick] = self.d['ConstructionMaterial'][brick]
- else:
- news.d[k] = self.d[k]
- return news
- # </STATE>
- # <INITIAL_STATE>
- COSTS = {"Red Brick": 40, "Ash Brick": 30, "Concrete": 20, 'NumberOfPlants': 5}
- bricks = lambda s : (s.d["ConstructionMaterial"].keys())
- brickToPeople = lambda s: sum([s.d["ConstructionMaterial"][key] for key in s.d["ConstructionMaterial"].keys()]) / 20
- brickSum = lambda s: sum([s.d["ConstructionMaterial"][key] for key in s.d["ConstructionMaterial"].keys()])
- INITIAL_STATE = State(
- {'ConstructionMaterial': {'Red Brick': 0, 'Ash Brick': 0, 'Concrete': 0}, 'EmissionPenalty': 0, 'NumberOfPlants': 0,
- 'PeopleServed': 0, 'cost': 0, 'budget': 10000})
- CREATE_INITIAL_STATE = lambda: INITIAL_STATE
- # </INITIAL_STATE>
- # <OPERATORS>
- build_combinations = [('Red Brick', 1000), ('Red Brick', -1000), ('Ash Brick', 1000),
- ('Ash Brick', -1000), ('Concrete', 1000), ('Concrete', -1000), ('NumberOfPlants', 5),
- ('NumberOfPlants', -5), ('PeopleServed', 10), ('PeopleServed', -10)]
- OPERATORS = [Operator("Change " + str(b_property) + " by " + str(amount),
- lambda s, b_property1=b_property, amount1=amount: can_build(s, b_property1, amount1),
- # The default value construct is needed
- # here to capture the values of p&q separately
- # in each iteration of the list comp. iteration.
- lambda s, b_property1=b_property, amount1=amount: build(s, b_property1, amount1))
- for (b_property, amount) in build_combinations]
- # </OPERATORS>
- # <GOAL_TEST>
- GOAL_TEST = lambda s: goal_test(s)
- # </GOAL_TEST>
- # <GOAL_MESSAGE_FUNCTION>
- GOAL_MESSAGE_FUNCTION = lambda s: goal_message(s)
- # </GOAL_MESSAGE_FUNCTION>
- # <HEURISTICS> (optional)
- def heuristic1(s):
- d = s.d
- return d["PeopleServed"] + d["NumberOfPlants"] - brickSum(s) - d["EmissionPenalty"]
- HEURISTICS = {'heuristic1': heuristic1}
- # </HEURISTICS>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement