Created
April 28, 2017 02:09
-
-
Save 5tigerjelly/71d53f076f798dd1879454d2acfe821a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment