SIMO Optimization task definition:
>>> epsilon = 0.00001
>>> from lxml import etree
>>> import datetime
>>> from simo.builder.optimization.opttask import OptimizationTaskDef
>>> tdf = open('../../simulator/xml/schemas/Typedefs_SIMO.xsd')
>>> typedef = tdf.read()
>>> tdf.close()
>>> sf = open('../../simulator/xml/schemas/optimization_task.xsd')
>>> schema = sf.read()
>>> sf.close()
>>> xml = '''<optimization_task
... xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
... xsi:schemaLocation="http://www.simo-project.org/simo
... ../schemas/optimization_task.xsd"
... xmlns="http://www.simo-project.org/simo">
... <initial_date>2008-01-01</initial_date>
... <period_step>year</period_step>
... <data_filter>comp_unit:SC eq 3</data_filter>
... <discount_rate>3.0</discount_rate>
... <conditional_discount>
... <rate>
... <condition>comp_unit:PRICE_REGION le 4</condition>
... <value>3.0</value>
... </rate>
... <rate>
... <condition>comp_unit:PRICE_REGION eq 5</condition>
... <value>2.0</value>
... </rate>
... </conditional_discount>
... <objective_function>
... <level>comp_unit</level>
... <type>
... <function>additive</function>
... <target>max</target>
... <scope>global</scope>
... </type>
... <sub_objectives>
... <sub_objective>
... <weight>1.0</weight>
... <expression>
... sum[1:10](operation:cash_flow:discount)
... </expression>
... <utility_function>
... <type>linear</type>
... </utility_function>
... </sub_objective>
... </sub_objectives>
... <constraints>
... <constraint max_violation="10" violation_metric="percentage">
... sum[6:10](operation:cash_flow) /
... sum[1:5](operation:cash_flow) lt 1.3
... </constraint>
... <constraint>
... sum[6:10](operation:cash_flow) /
... sum[1:5](operation:cash_flow) gt 0.7
... </constraint>
... </constraints>
... </objective_function>
... </optimization_task>'''
>>> class Lexicon(object):
... def get_level_ind(self, level):
... return 1
... def get_variable_ind(self, level, var, active=False):
... return (1, 1)
>>> otd = OptimizationTaskDef(typedef)
>>> otd.schema = schema
>>> try:
... otd.xml = xml
... except ValueError, e:
... print e
name, xml content and lexicon instance must be passed
>>> otd.xml = ('optimization-task', xml, Lexicon())
>>> otd.xml['optimization-task'][0:18]
'<optimization_task'
Optimization task definition
>>> opt = otd.obj['optimization-task']
Parse optimization task definition XML
>>> opt.init_date
datetime.date(2008, 1, 1)
>>> opt.period_step
'year'
>>> opt.discount_rate
3.0
>>> opt.main_level
'comp_unit'
>>> opt.data_filter
[('data', ('comp_unit', 'SC')), ('value', 3.0), ('eq', <function eee at ...>)]
>>> opt.conditional_discounting
[('comp_unit:PRICE_REGION le 4',
[('data', ('comp_unit', 'PRICE_REGION')),
('value', 4.0), ('eq', <function lee at ...>)], 3.0),
('comp_unit:PRICE_REGION eq 5',
[('data', ('comp_unit', 'PRICE_REGION')),
('value', 5.0), ('eq', <function eee at ...>)], 2.0)]
Parameters :
root – XML root element
Parse conditional discounting rates
Parse optimization data filter expression
Parse date expression from xs:date format into datetime.date object:
>>> xml = u'''<initial_date>2008-01-01</initial_date>'''
>>> elem = etree.fromstring(xml)
>>> opt._parse_date(elem)
datetime.date(2008, 1, 1)
>>> xml = u'''<initial_date>today</initial_date>'''
>>> elem = etree.fromstring(xml)
>>> opt._parse_date(elem) == datetime.date.today()
True
Parse objective function definition:
>>> opt._objective_func.type
'additive'
>>> opt._objective_func.target
'max'
>>> opt._objective_func.scope
'global'
Parse objective function subobjectives:
>>> for i in opt._subobjectives[0].expr: print i
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)), None, True, (0, 0))
('aggr', <function sum at ...>)
Parse optimization task constraint expressions:
>>> for i in opt._constraints[0].expr:
... if i[0] != 'value':
... print i
... else:
... print (i[0], '%.2f' % i[1])
...
('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (1, 1))
('aggr', <function sum at ...>)
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (2, 1))
('aggr', <function sum at ...>)
('ari', <function divide at ...>, '/')
('value', '1.30')
('eq', <function lte at ...>, 'lt')
>>> for i in opt._constraints[1].expr:
... if i[0] != 'value':
... print i
... else:
... print (i[0], '%.2f' % i[1])
...
('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (3, 1))
('aggr', <function sum at ...>)
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (4, 1))
('aggr', <function sum at ...>)
('ari', <function divide at ...>, '/')
('value', '0.70')
('eq', <function gte at ...>, 'gt')
Parse subobjective utility function definition:
>>> xml = u'''<utility_function>
... <type>linear</type>
... </utility_function>'''
>>> elem = etree.fromstring(xml)
>>> ufunc = opt._parse_utility_function(elem)
>>> ufunc.type
'linear'
Go through each subobjective constraint expression and all operands of each expression and construct index of unique operands.
All subobjective and constraint operands are mapped to unique operands and in optimization data matrix, all data processing is done to the unique operands which saves a lot of memory with large data sets.
Unique operands contain variable name, level, constraint and discounting info (no date information)
>>> opt._unify_operands()
>>> opt._operand_index[0]
0
>>> opt._operand_index[1]
1
>>> opt._operand_index[2]
1
>>> opt._operand_index[3]
1
>>> opt._operand_index[4]
1
>>> opt._unique_operands[('op', u'cash_flow', None, True)]
0
>>> opt._unique_operands[('op', u'cash_flow', None, False)]
1
>>> opt.date_ranges[0]
(datetime.date(2008, 1, 1), datetime.date(2017, 12, 31))
>>> opt.date_ranges[1]
(datetime.date(2008, 1, 1), datetime.date(2017, 12, 31))
Process a single subobjective or constraint expression and update unique operand index
Parameters:
expression -- parsed expression in postfix form
expr_type -- expression type, either 's' for subobjective or 'c' for
constraint
i -- expression indice
Give new initial date, and fix all subobjectives to match.
Parameters
new_date -- a datetime.date object
>>> opt._init_date
datetime.date(2008, 1, 1)
>>> for subobj in opt._subobjectives: print subobj.expr
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2017, 12, 31)),
None, True, (0, 0), (5, 2)), ('aggr', <function sum at ...>)]
>>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[[('op', u'cash_flow', (datetime.date(2013, 1, 1),
datetime.date(2017, 12, 31)),
None, False, (1, 1), (6, 3)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2012, 12, 31)),
None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 1.3),
('eq', <function lte at ...>, 'lt')],
[('op', u'cash_flow', (datetime.date(2013, 1, 1),
datetime.date(2017, 12, 31)),
None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2012, 12, 31)),
None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 0...),
('eq', <function gte at ...>, 'gt')]]
>>> opt.update_init_date(datetime.date(2012, 12, 13))
>>> opt._init_date
datetime.date(2012, 12, 13)
>>> for subobj in opt._subobjectives: print subobj.expr
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[('op', u'cash_flow', (datetime.date(2012, 12, 13),
datetime.date(2022, 12, 12)),
None, True, (0, 0), (5, 2)), ('aggr', <function sum at ...>)]
>>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[[('op', u'cash_flow', (datetime.date(2017, 12, 13),
datetime.date(2022, 12, 12)),
None, False, (1, 1), (6, 3)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2012, 12, 13),
datetime.date(2017, 12, 12)),
None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 1.3),
('eq', <function lte at ...>, 'lt')],
[('op', u'cash_flow', (datetime.date(2017, 12, 13),
datetime.date(2022, 12, 12)),
None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2012, 12, 13),
datetime.date(2017, 12, 12)),
None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 0...),
('eq', <function gte at ...>, 'gt')]]
>>> opt.update_init_date(datetime.date(2008, 1, 1))
>>> for subobj in opt._subobjectives: print subobj.expr
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2017, 12, 31)),
None, True, (0, 0), (5, 2)), ('aggr', <function sum at ...>)]
>>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[[('op', u'cash_flow', (datetime.date(2013, 1, 1),
datetime.date(2017, 12, 31)),
None, False, (1, 1), (6, 3)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2012, 12, 31)),
None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 1.3),
('eq', <function lte at ...>, 'lt')],
[('op', u'cash_flow', (datetime.date(2013, 1, 1),
datetime.date(2017, 12, 31)),
None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
('op', u'cash_flow', (datetime.date(2008, 1, 1),
datetime.date(2012, 12, 31)),
None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
('ari', <function divide at ...>, '/'), ('value', 0...),
('eq', <function gte at ...>, 'gt')]]