martineau

surprising-challenge-generating-comprehensive-python-list.py

Dec 15th, 2016
113
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from itertools import permutations, combinations_with_replacement
  2.  
  3. _profiling = True  # profiling toggle
  4.  
  5. if _profiling:
  6.     from cProfile import Profile
  7.     from pstats import Stats
  8.     prof = Profile()
  9.     prof.disable()
  10.  
  11. def join_adjacent_repeated_materials(potential_structure):
  12.     """
  13.    Self-explanitory...
  14.    """
  15.     #print potential_structure
  16.  
  17.     new_layers = [] # List to hold re-cast structure
  18.     for layer in potential_structure:
  19.         if len(new_layers) > 0: # if not the first item in the list of layers
  20.             last_layer=new_layers[-1] # last element of existing layer list
  21.             if layer[0] == last_layer[0]: # true is the two layers are the same material
  22.                 combined_layer = (layer[0], layer[1] + last_layer[1])
  23.                 new_layers[len(new_layers)-1] = combined_layer
  24.             else: # adjcent layers are different material so no comibantion is possible
  25.                 new_layers.append(layer)
  26.         else: # for the first layer
  27.             new_layers.append(layer)
  28.  
  29.     return tuple(new_layers)
  30.  
  31. def calculate_unique_structure_lengths(thicknesses, materials, maximum_number_of_layers,\
  32.                                        maximum_individual_layer_thicknesses, \
  33.                                        maximum_total_material_thicknesses):
  34.     """
  35.    Create a set on all possible multilayer combinations.
  36.  
  37.    thicknesses : if this contains '0' the total number of layers will vary
  38.                  from 0 to maximum_number_of_layers, otherwise, the
  39.                  number total number layers will always be maximum_number_of_layers
  40.                  e.g. arange(0 , 100, 5)
  41.  
  42.    materials : list of materials used
  43.                e.g. ['Metal', 'Dielectric']
  44.  
  45.    maximum_number_of_layers : pretty self-explanitory...
  46.                               e.g. 5
  47.  
  48.    maximum_individual_layer_thicknesses : filters the created the multilayer structures
  49.                                           preventing the inclusion layers that are too thick
  50.                                           - this is important after the joining of
  51.                                           adjacent materials
  52.                                           e.g. (('Metal',30),('Dielectric',20))
  53.  
  54.    maximum_total_material_thicknesses : similar to the above but filters structures where the total
  55.                                         amount of a particular material is exceeded
  56.                                         e.g. (('Metal',50),('Dielectric',100))
  57.  
  58.  
  59.    """
  60.     # generate all possible thickness combinations and material combinations
  61.     all_possible_thickness_sets = set(permutations(combinations_with_replacement(thicknesses, maximum_number_of_layers)))
  62.     all_possible_layer_material_orders = set(permutations(combinations_with_replacement(materials, maximum_number_of_layers)))
  63.  
  64.  
  65.     first_set = set() # Create set object (list of unique elements, no repeats)
  66.     for layer_material_order in all_possible_layer_material_orders:
  67.         for layer_thickness_set in all_possible_thickness_sets:
  68.             potential_structure = [] # list to hold this structure
  69.             for layer, thickness in zip(layer_material_order[0], layer_thickness_set[0]): # combine the layer thickness with its material
  70.                 if thickness != 0: # layers of zero thickness are not added to potential_structure
  71.                     potential_structure.append((layer, thickness))
  72.             first_set.add(tuple(potential_structure)) # add this potential_structure to the first_set set
  73.  
  74.     #print('first_set')
  75.     #for struct in first_set:
  76.     #    print struct
  77.  
  78.     ## join adjacent repeated materials
  79.     second_set = set() # create new set
  80.     for potential_structure in first_set:
  81.         second_set.add(join_adjacent_repeated_materials(potential_structure))
  82.  
  83.     ## remove structures where a layer is too thick
  84.     third_set = set()
  85.     for potential_structure in second_set: # check all the structures in the set
  86.         conditions_satisfied=True # default
  87.         for max_condition in maximum_individual_layer_thicknesses: # check this structure using each condition
  88.             for layer in potential_structure: # examine each layer
  89.                 if layer[0] == max_condition[0]: # match condition with material
  90.                     if layer[1] > max_condition[1]: # test thickness condition
  91.                         conditions_satisfied=False
  92.         if conditions_satisfied:
  93.             third_set.add(potential_structure)
  94.  
  95.     ##remove structures that contain too much of a certain material
  96.     fourth_set = set()
  97.     for potential_structure in second_set: # check all the structures in the set
  98.         conditions_satisfied=True # default
  99.         for max_condition in maximum_total_material_thicknesses: # check this structure using each condition
  100.             amount_of_material_in_this_structure = 0 # initialise a counter
  101.             for layer in potential_structure: # examine each layer
  102.                 if layer[0] == max_condition[0]: # match condition with material
  103.                     amount_of_material_in_this_structure += layer[1]
  104.                     if amount_of_material_in_this_structure > max_condition[1]: # test thickness condition
  105.                         conditions_satisfied=False
  106.         if conditions_satisfied:
  107.             fourth_set.add(potential_structure)
  108.  
  109.     return fourth_set
  110.  
  111. thicknesses = [0,1,2]
  112. materials = ('A', 'B') # Tuple cannot be accidentally appended to later
  113. maximum_number_of_layers = 3
  114. maximum_individual_layer_thicknesses=(('A',30),('B',20))
  115. maximum_total_material_thicknesses=(('A',20),('B',15))
  116.  
  117. if _profiling:
  118.     prof.enable()
  119.  
  120. calculate_unique_structure_lengths(thicknesses, materials, maximum_number_of_layers,\
  121.                                    maximum_individual_layer_thicknesses = maximum_individual_layer_thicknesses, \
  122.                                    maximum_total_material_thicknesses = maximum_total_material_thicknesses)
  123.  
  124. if _profiling:
  125.     prof.disable()
  126.     prof.dump_stats('unique.stats')
  127.     with open('unique_stats.txt', 'wt') as output:
  128.         stats = Stats('unique.stats', stream=output)
  129.         stats.strip_dirs().sort_stats('cumulative', 'time')
  130.         stats.sort_stats('cumulative', 'time')
  131.         stats.print_stats()
RAW Paste Data