def test_load_file(self): a = Amply("param T:= 4; param X{foo};") try: s = StringIO("param S := 6; param X := 1 2;") except TypeError: s = StringIO(u"param S := 6; param X := 1 2;") a.load_file(s) assert a.T == 4 assert a.S == 6 assert a.X[1] == 2
def read_in_datafile(path_to_datafile: str, config: Dict) -> Amply: """Read in a datafile using the Amply parsing class Arguments --------- path_to_datafile: str config: Dict """ parameter_definitions = load_parameter_definitions(config) datafile_parser = Amply(parameter_definitions) logger.debug(datafile_parser) with open(path_to_datafile, "r") as datafile: datafile_parser.load_file(datafile) return datafile_parser
def parse_ampl_results(filename='results.txt'): data = Amply(""" set PrimaryPath{REQUESTS}; set DetourPath{NODES, NODES, REQUESTS}; param DetectNode{NODES, NODES, REQUESTS}; """) data.load_file(open(filename)) requests = dict() faults = dict() stats = dict() pp_edges = dict() print "Parsing requests..." for i in data.PrimaryPath: rid = int(i) pp = [int(x) for x in data.PrimaryPath[rid]] pp_edge = (pp[0], pp[-1]) requests[pp_edge] = { 'pp_edge': pp_edge, 'primary_path': pp, 'faults': dict()} pp_edges[rid] = pp_edge #print rid, pp_edge, pp for i in data.DetectNode.data: na = int(i) val_na = data.DetectNode.data[na] for j in val_na: nb = int(j) val_nb = val_na[j] # if (nb > na): # continue # if (nb == 0): # fault_type = 'node' # fid = "N-" + str(na) # else: # fault_type = 'link' # fid = "L-" + str(na) + "-" + str(nb) for d in val_nb: rid = int(d) if na < nb: fault_edge = (na, nb) else: fault_edge = (nb, na) pp_edge = pp_edges[rid] pp = requests[pp_edge]['primary_path'] detect_node = int(val_nb[rid]) dp = [int(x) for x in data.DetourPath.data[na][nb][rid]] redirect_node = dp[0] # Fw back path is the sequence of node from detect to redirect node (included) idx_d = pp.index(detect_node) idx_r = pp.index(redirect_node) if(idx_d - idx_r == 0): fw_back_path = None else: fw_back_path = pp[idx_r:idx_d + 1] fault = {'detect_node': detect_node, 'redirect_node': redirect_node, 'detour_path': dp, 'fw_back_path': fw_back_path} # For each request, we populate the corresponding faults... requests[pp_edge]['faults'][fault_edge] = fault # And viceversa, for each fault, we populate the requests... if fault_edge not in faults: faults[fault_edge] = { 'requests': {}} faults[fault_edge]['requests'][pp_edge] = { 'primary_path': pp, 'detect_node': detect_node, 'redirect_node': redirect_node, 'detour_path': dp, 'fw_back_path': fw_back_path} with open('./tmp/' + hh + '-requests.p', 'wb') as fp: pickle.dump(requests, fp) with open('./tmp/' + hh + '-faults.p', 'wb') as fp: pickle.dump(faults, fp) return requests, faults
def amply_quickstart_guide(): from pulp import Amply # A simple set. Sets behave a lot like lists. data = Amply("set CITIES := Auckland Wellington Christchurch;") print("Cities: {}.".format(data.CITIES)) print("Cities: {}.".format(data['CITIES'])) assert data.CITIES == ['Auckland', 'Hamilton', 'Wellington'] for c in data.CITIES: print(c) # Data can be integers, reals, symbolic, or quoted strings. data = Amply(""" set BitsNPieces := 0 3.2 -6e4 Hello "Hello, World!"; """) print("BitsNPieces: {}.".format(data.BitsNPieces)) # Sets can contain multidimensional data. data = Amply(""" set pairs dimen 2; set pairs := (1, 2) (2, 3) (3, 4); """) print("pairs: {}.".format(data.pairs)) #-------------------- #Amply.load_string(string) #Amply.load_file(file) # Parse contents of file or file-like object. #Amply.load_string(file) # Static. Create Amply object from contents of file or file-like object. data = Amply(""" set CITIES; set ROUTES dimen 2; param COSTS{ROUTES}; param DISTANCES{ROUTES}; """) for data_file in ('cities.dat', 'routes.dat', 'costs.dat', 'distances.dat'): data.load_file(open(data_file)) #-------------------- # Sets themselves can be multidimensional (i.e. be subscriptable). # The set COUNTRIES didn’t actually have to exist itself. # Amply does not perform any validation on subscripts, it only uses them to figure out how many subscripts a set has. data = Amply(""" set CITIES{COUNTRIES}; set CITIES[Australia] := Adelaide Melbourne Sydney; set CITIES[Italy] := Florence Milan Rome; """) print("CITIES['Australia']: {}.".format(data.CITIES['Australia'])) print("CITIES['Italy']: {}.".format(data.CITIES['Italy'])) # To specify more than one, separate them by commas. data = Amply(""" set SUBURBS{COUNTRIES, CITIES}; set SUBURBS[Australia, Melbourne] := Docklands 'South Wharf' Kensington; """) print("SUBURBS['Australia', 'Melbourne']: {}.".format(data.SUBURBS['Australia', 'Melbourne'])) #-------------------- # Slices can be used to simplify the entry of multi-dimensional data. data = Amply(""" set TRIPLES dimen 3; set TRIPLES := (1, 1, *) 2 3 4 (*, 2, *) 6 7 8 9 (*, *, *) (1, 1, 1); """) print("TRIPLES: {}.".format(data.TRIPLES)) # [(1, 1, 2), (1, 1, 3), (1, 1, 4), (6, 2, 7), (8, 2, 9), (1, 1, 1)]. # Set data can also be specified using a matrix notation. # A '+' indicates that the pair is included in the set whereas a '-' indicates a pair not in the set. data = Amply(""" set ROUTES dimen 2; set ROUTES : A B C D := E + - - + F + + - - ; """) print("ROUTES: {}.".format(data.ROUTES)) # [('E', 'A'), ('E', 'D'), ('F', 'A'), ('F', 'B')]. # Matrices can also be transposed. data = Amply(""" set ROUTES dimen 2; set ROUTES (tr) : E F := A + + B - + C - - D + - ; """) print("ROUTES: {}.".format(data.ROUTES)) # [('E', 'A'), ('F', 'A'), ('F', 'B'), ('E', 'D')]. # Matrices only specify 2d data, however they can be combined with slices to define higher-dimensional data. data = Amply(""" set QUADS dimen 2; set QUADS := (1, 1, *, *) : 2 3 4 := 2 + - + 3 - + + (1, 2, *, *) : 2 3 4 := 2 - + - 3 + - - ; """) print("QUADS: {}.".format(data.QUADS)) # [(1, 1, 2, 2), (1, 1, 2, 4), (1, 1, 3, 3), (1, 1, 3, 4), (1, 2, 2, 3), (1, 2, 3, 2)]. #-------------------- # Parameters are also supported. data = Amply(""" param T := 30; param n := 5; """) print("T: {}.".format(data.T)) print("n: {}.".format(data.n)) # Parameters are commonly indexed over sets. # No validation is done by Amply, and the sets do not have to exist. # Parameter objects are represented as a mapping. data = Amply(""" param COSTS{PRODUCTS}; param COSTS := FISH 8.5 CARROTS 2.4 POTATOES 1.6 ; """) print("COSTS: {}.".format(data.COSTS)) print("COSTS['FISH']: {}.".format(data.COSTS['FISH'])) # Parameter data statements can include a default clause. # If a '.' is included in the data, it is replaced with the default value. data = Amply(""" param COSTS{P}; param COSTS default 2 := F 2 E 1 D . ; """) print("COSTS['D']: {}.".format(data.COSTS['D'])) # Parameter declarations can also have a default clause. # For these parameters, any attempt to access the parameter for a key that has not been defined will return the default value. data = Amply(""" param COSTS{P} default 42; param COSTS := F 2 E 1 ; """) print("COSTS['DOES NOT EXIST']: {}.".format(data.COSTS['DOES NOT EXIST'])) # Parameters can be indexed over multiple sets. # The resulting values can be accessed by treating the parameter object as a nested dictionary, or by using a tuple as an index. data = Amply(""" param COSTS{CITIES, PRODUCTS}; param COSTS := Auckland FISH 5 Auckland CHIPS 3 Wellington FISH 4 Wellington CHIPS 1 ; """) print("COSTS: {}.".format(data.COSTS)) # {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}. print("COSTSCOSTS['Wellington']['CHIPS']: {}.".format(data.COSTSCOSTS['Wellington']['CHIPS'])) # Nested dict as key. print("COSTS['Wellington', 'CHIPS']: {}.".format(data.COSTS['Wellington', 'CHIPS'])) # Tuple as key. # Parameters support a slice syntax similar to that of sets. data = Amply(""" param COSTS{CITIES, PRODUCTS}; param COSTS := [Auckland, *] FISH 5 CHIPS 3 [Wellington, *] FISH 4 CHIPS 1 ; """) print("COSTS: {}.".format(data.COSTS)) # {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}. # Parameters indexed over two sets can also be specified in tabular format. data = Amply(""" param COSTS{CITIES, PRODUCTS}; param COSTS: FISH CHIPS := Auckland 5 3 Wellington 4 1 ; """) print("COSTS: {}.".format(data.COSTS)) # {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}. # Tabular data can also be transposed. data = Amply(""" param COSTS{CITIES, PRODUCTS}; param COSTS (tr): Auckland Wellington := FISH 5 4 CHIPS 3 1 ; """) print("COSTS: {}.".format(data.COSTS)) # {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}. # Slices can be combined with tabular data for parameters indexed over more than 2 sets. data = Amply(""" param COSTS{CITIES, PRODUCTS, SIZE}; param COSTS := [Auckland, *, *] : SMALL LARGE := FISH 5 9 CHIPS 3 5 [Wellington, *, *] : SMALL LARGE := FISH 4 7 CHIPS 1 2 ; """) print("COSTS: {}.".format(data.COSTS)) # {'Wellington': {'FISH': {'SMALL': 4.0, 'LARGE': 7.0}, 'CHIPS': {'SMALL': 1.0, 'LARGE': 2.0}}, 'Auckland': {'FISH': {'SMALL': 5.0, 'LARGE': 9.0}, '.