def post_solve(m, outputs_dir): # save any requested data if not m.options.no_cross_time_duals: # these will be applied as prices for variables. # each constraint/variable has different indexing, so write them in variable-length, # tab-separated format, with variable name, then indexes, then values with open(os.path.join(m.options.outputs_dir, 'cross_time_duals.tab'), 'w') as f: for component in get_period_constraints(m): constraint_name = component.name # note: we assume every item is indexed; otherwise we need to branch here on c.is_indexed() for key, c in component.items(): row = (constraint_name, ) + tuple( make_iterable(key)) + (m.dual.get(c, None), ) f.write('\t'.join(map(str, row)) + '\n') if m.options.save_relaxation_bid: if not m.options.add_cross_time_relaxation_variables: raise ValueError( "The --save-relaxation-bid option cannot be used without " "the --add-cross-time-relaxation-variables option.") with open(os.path.join(m.options.outputs_dir, 'relaxation_bid.tab'), 'w') as f: for constraint in get_period_constraints(m): var_component = getattr(m, relax_var_name(constraint)) for key, var_obj in var_component.items(): if var_obj.value is not None: # ignore relaxation variables for skipped constraints row = (constraint.name, ) + tuple( make_iterable(key)) + (value(var_obj), ) f.write('\t'.join(map(str, row)) + '\n') # also save total cost f.write('SystemCost\t{}\n'.format(value(m.SystemCost)))
def save_generic_results(instance, outdir, sorted_output): components = list(instance.component_objects(Var)) # add Expression objects that should be saved, if any if 'none' in instance.options.save_expressions: # drop everything up till the last 'none' (users may have added more after that) last_none = ( len(instance.options.save_expressions) - instance.options.save_expressions[::-1].index('none') ) instance.options.save_expressions = instance.options.save_expressions[last_none:] if 'all' in instance.options.save_expressions: components += list(instance.component_objects(Expression)) else: components += [getattr(instance, c) for c in instance.options.save_expressions] for var in components: output_file = os.path.join(outdir, '%s.tab' % var.name) with open(output_file, 'wb') as fh: writer = csv.writer(fh, dialect='ampl-tab') if var.is_indexed(): index_name = var.index_set().name # Write column headings writer.writerow(['%s_%d' % (index_name, i + 1) for i in xrange(var.index_set().dimen)] + [var.name]) # Results are saved in a random order by default for # increased speed. Sorting is available if wanted. items = sorted(var.items()) if sorted_output else var.items() for key, obj in items: writer.writerow(tuple(make_iterable(key)) + (get_value(obj),)) else: # single-valued variable writer.writerow([var.name]) writer.writerow([get_value(obj)])
def save_generic_results(instance, outdir, sorted_output): components = list(instance.component_objects(Var)) # add Expression objects that should be saved, if any if 'none' in instance.options.save_expressions: # drop everything up till the last 'none' (users may have added more after that) last_none = ( len(instance.options.save_expressions) - instance.options.save_expressions[::-1].index('none') ) instance.options.save_expressions = instance.options.save_expressions[last_none:] if 'all' in instance.options.save_expressions: components += list(instance.component_objects(Expression)) else: components += [getattr(instance, c) for c in instance.options.save_expressions] for var in components: output_file = os.path.join(outdir, '%s.csv' % var.name) with open(output_file, 'w') as fh: writer = csv.writer(fh, dialect='switch-csv') if var.is_indexed(): index_name = var.index_set().name # Write column headings writer.writerow(['%s_%d' % (index_name, i + 1) for i in range(var.index_set().dimen)] + [var.name]) # Results are saved in a random order by default for # increased speed. Sorting is available if wanted. items = sorted(var.items()) if sorted_output else list(var.items()) for key, obj in items: writer.writerow(tuple(make_iterable(key)) + (get_value(obj),)) else: # single-valued variable writer.writerow([var.name]) writer.writerow([get_value(obj)])
def fix_var(m, var, source_dir): try: # check types of the first tuple of keys for this variable key_types = [type(i) for i in make_iterable(next(var.iterkeys()))] except StopIteration: key_types = [] # no keys with open(os.path.join(source_dir, var.name + '.tab')) as f: next(f) # skip headers # set variable values using values from .tab file for r in f: row = r.strip().split('\t') keys = tuple(t(k) for t, k in zip(key_types, row[:-1])) # print "trying to set {}[{}] = {}".format(var, keys, row[-1]) try: v = var[keys] except KeyError: raise KeyError( "Unable to set value for {}[{}]; index is invalid.".format( var.name, keys)) else: val = float(row[-1]) if v.is_integer() or v.is_binary(): val = int(val) v.value = val v.fixed = True # see p. 171 of the Pyomo book if m.options.verbose: print "Set {} = {}".format(v.name, val)
def cost_rule(m): with open(m.options.cross_time_relaxation_price_file) as f: # read all values from the file rows = [r.strip().split('\t') for r in f] price_dict = {tuple(r[:-1]): float(r[-1]) for r in rows} total_cost = 0.0 for component in get_period_constraints(m): var_name = relax_var_name(component) component_name = component.name for key, c in component.items(): k = (component_name, ) + tuple( str(i) for i in make_iterable(key)) price = price_dict[k] var = getattr(m, var_name)[key] # matching relaxation var total_cost += price * var return m.SystemCost + total_cost
def reload_prior_solution_from_csvs(instance): """ Assign values to all model variables from <variable>.csv files saved after previous solution. (Not currently used.) """ import csv var_objects = instance.component_objects(Var) for var in var_objects: var_file = os.path.join(instance.options.outputs_dir, '{}.csv'.format(var.name)) if not os.path.isfile(var_file): raise RuntimeError( "Tab output file for variable {} cannot be found in outputs " "directory. Exiting.".format(var.name) ) try: # check types of the first tuple of keys for this variable key_types = [type(i) for i in make_iterable(next(var.iterkeys()))] except StopIteration: key_types = [] # no keys with open(var_file,'r') as f: reader = csv.reader(f, delimiter=',') next(reader) # skip headers for row in reader: index = tuple(t(k) for t, k in zip(key_types, row[:-1])) try: v = var[index] except KeyError: raise KeyError( "Unable to set value for {}[{}]; index is invalid." .format(var.name, keys) ) if row[-1] == '': # Variables that are not used in the model end up with no # value after the solve and get saved as blanks; we skip those. continue val = float(row[-1]) if v.is_integer() or v.is_binary(): val = int(val) v.value = val if instance.options.verbose: print('Loaded variable {} values into instance.'.format(var.name))
def reload_prior_solution_from_tabs(instance): """ Assign values to all model variables from <variable>.tab files saved after previous solution. (Not currently used.) """ import csv var_objects = instance.component_objects(Var) for var in var_objects: var_file = os.path.join(instance.options.outputs_dir, '{}.tab'.format(var.name)) if not os.path.isfile(var_file): raise RuntimeError( "Tab output file for variable {} cannot be found in outputs " "directory. Exiting.".format(var.name) ) try: # check types of the first tuple of keys for this variable key_types = [type(i) for i in make_iterable(next(var.iterkeys()))] except StopIteration: key_types = [] # no keys with open(var_file,'r') as f: reader = csv.reader(f, delimiter='\t') next(reader) # skip headers for row in reader: index = tuple(t(k) for t, k in zip(key_types, row[:-1])) try: v = var[index] except KeyError: raise KeyError( "Unable to set value for {}[{}]; index is invalid." .format(var.name, keys) ) if row[-1] == '': # Variables that are not used in the model end up with no # value after the solve and get saved as blanks; we skip those. continue val = float(row[-1]) if v.is_integer() or v.is_binary(): val = int(val) v.value = val if instance.options.verbose: print 'Loaded variable {} values into instance.'.format(var.name)
def save_generic_results(instance, outdir, sorted_output): for var in instance.component_objects(Var): output_file = os.path.join(outdir, '%s.tab' % var.name) with open(output_file, 'wb') as fh: writer = csv.writer(fh, dialect='ampl-tab') if var.is_indexed(): index_name = var.index_set().name # Write column headings writer.writerow(['%s_%d' % (index_name, i + 1) for i in xrange(var.index_set().dimen)] + [var.name]) # Results are saved in a random order by default for # increased speed. Sorting is available if wanted. for key, obj in (sorted(var.items()) if sorted_output else var.items()): writer.writerow(tuple(make_iterable(key)) + (obj.value,)) else: # single-valued variable writer.writerow([var.name]) writer.writerow([value(obj)])
def pre_solve(m): if m.options.verbose: print "Setting build variables from {}...".format( m.options.fix_build_vars_source_dir) # double-check that there aren't any variables indexed by period but missing from these lists # (this check isn't foolproof, but it's pretty good) period_vars = { c.name for c in m.component_objects(po.Var) if any( k == m.PERIODS.first() for keys in c.iterkeys() for k in make_iterable(keys)) and not c.name.startswith('Relax_') } missing_vars = period_vars - fix_vars - free_vars if missing_vars: print "=" * 80 print "WARNING: the following per-period variables are not in the lists of fixed or free variables:" print " " + ','.join(sorted(missing_vars)) print "They will be left free." print "=" * 80 time.sleep(2) # make sure they notice build_vars = [getattr(m, v) for v in fix_vars if hasattr(m, v)] for var in build_vars: fix_var(m, var, m.options.fix_build_vars_source_dir)