My code gives me this incorrect output:
['CT', 'X', 'Z']
[100, 1.0583, 1.0633]
[200, 3.012, 5.873600000000001]
[300, 1.79, 2.5220000000000002]
['Total', 0, 0]
The reason is that 5.873600000000001
is incorrectly calculated because according to list_components_and_hierarchical_relationships
, it is indicated that Z is a quantity of 1: ['Z', ['PRODUCT', 1]]
. Then,
['F', [['Z', 3]]]
['G', [['F', 1]]]
Then we can build another branch, where Z is a quantity of 1: ['Z', ['PRODUCTO', 1]]
, and E has a quantity of 4: ['E', [['Z', 4]]]
. G depends on E with a quantity of 2: ['G', [['E', 2]]]
, leaving the calculation as follows:
0.4804 * 1 * 3 + 0.351 * 1 * 2 + 0.77 * 1 * 4 + 0.2168 * 1 * 4 * 2 + 0.2168 * 1 * 3 * 1 = 7.608
This should be the "correct output":
capacity_list = [
['CT', 'X', 'Z'],
[100, 1.0583 * 1, 1.0633 * 1],
[200, 0.351 * 1 * 2 + 0.77 * 1 * 3, 0.4804 * 1 * 3 + 0.351 * 1 * 2 + 0.77 * 1 * 4 + 0.2168 * 1 * 4 * 2 + 0.2168 * 1 * 3 * 1],
[300, 0.895 * 1 * 2, 0.895 * 1 * 2 + 0.244 * 1 * 3],
['Total']
]
Here is my code:
# Initial data
routing_info_list = [
['Art.', 'CT', 'Batch_Size', 'Setup_Time', 'Unit_Run_Time'],
['X', 100, 30, 0.0083, 1.0583],
['Z', 100, 30, 0.0033, 1.0633],
['D', 200, 40, 0.011, 0.351],
['D', 300, 30, 0.015, 0.895],
['E', 200, 10, 0.0, 0.77],
['F', 200, 25, 0.0304, 0.4804],
['F', 300, 50, 0.004, 0.244],
['G', 200, 25, 0.0068, 0.2168]
]
capacity_list = [
['CT', 'X', 'Z'],
[100],
[200],
[300],
['Total']
]
# Represents the component relationship scheme in first image
list_components_and_hierarchical_relationships = [
[
['X', ['PRODUCT', 1]],
['D', [['X', 2]]],
['E', [['X', 3]]]
],
[
['Z', ['PRODUCT', 1]],
['F', [['Z', 3]]],
['D', [['Z', 2]]],
['E', [['Z', 4]]],
['G', [['F', 1]]],
['G', [['E', 2]]]
]
]
This code seeks to determine the total execution times of the components in a production or manufacturing process, taking into account the dependency relationships between the different components and subcomponents.
# Function to search for Unit_Run_Time in routing_info_list
def search_execution_time_func(articulo, ct):
for row in routing_info_list[1:]:
if row[0] == articulo and row[1] == ct:
return row[4]
return None
# Function to process a product
def process_product_info_func(components, ct):
total_time = 0
for component, dependencies in components:
run_time = search_execution_time_func(component, ct)
if run_time is not None:
# Multiply by the dependencies
total_quantity = 1
for dep in dependencies:
if isinstance(dep, list) and dep[0] != 'PRODUCT':
total_quantity *= dep[1]
print( str(run_time) + " hrs * " + str(total_quantity) )
total_time += run_time * total_quantity
return total_time
# Process each CT row from the product capacity list for each column
for row in capacity_list[1:]:
ct = row[0]
times = []
for product_idx, product in enumerate(list_components_and_hierarchical_relationships):
total_time = process_product_info_func(product, ct)
times.append(total_time)
row.extend(times)
# Calculate the 'Total' row
# Get the number of columns, excluding 'CT'
num_columns = len(capacity_list[0]) - 1
# Sum the values of each column, ignoring the header row and the 'CT' column
for col in range(1, num_columns + 1):
total_sum = sum(row[col] for row in capacity_list[1:-1])
capacity_list[-1][col] = total_sum
# Display the final result
for row in capacity_list: print(row)
What should I do to correct it, and tell me how it would give the correct output, adding the terms of each branch of the components according to the diagram?
For this task I'd use networkx module:
import networkx as nx
def create_hierarchical_graph(relationships_list):
for relationships in relationships_list:
G = nx.DiGraph()
root = None
for item in relationships:
node = item[0]
connections = item[1]
if connections[0] == "PRODUCT":
G.add_edge("PRODUCT", node, weight=connections[1])
root = node
else:
for connection in connections:
parent_node = connection[0]
weight = connection[1]
G.add_edge(parent_node, node, weight=weight)
yield G, root
def get_weight(G, path):
total = 1
for u, v in zip(path[:-1], path[1:]):
total *= G.edges[u, v]["weight"]
return total
list_components_and_hierarchical_relationships = [
[
["X", ["PRODUCT", 1]],
["D", [["X", 2]]],
["E", [["X", 3]]],
],
[
["Z", ["PRODUCT", 1]],
["F", [["Z", 3]]],
["D", [["Z", 2]]],
["E", [["Z", 4]]],
["G", [["F", 1]]],
["G", [["E", 2]]],
],
]
routing_info_list = [
["Art.", "CT", "Batch_Size", "Setup_Time", "Unit_Run_Time"],
["X", 100, 30, 0.0083, 1.0583],
["Z", 100, 30, 0.0033, 1.0633],
["D", 200, 40, 0.011, 0.351],
["D", 300, 30, 0.015, 0.895],
["E", 200, 10, 0.0, 0.77],
["F", 200, 25, 0.0304, 0.4804],
["F", 300, 50, 0.004, 0.244],
["G", 200, 25, 0.0068, 0.2168],
]
# transform routing info list to
# easily find unit run time
unit_run_times = {}
for l in routing_info_list[1:]:
unit_run_times.setdefault(l[1], {}).setdefault(l[0], {})
unit_run_times[l[1]][l[0]] = l[-1]
for G, root in create_hierarchical_graph(list_components_and_hierarchical_relationships):
print(f"{root=}")
for CT in [100, 200, 300]:
s = 0
for a in unit_run_times[CT]:
for p in nx.all_simple_paths(G, "PRODUCT", a):
s += get_weight(G, p) * unit_run_times[CT][a]
print(CT, s)
print("-" * 80)
Prints:
root='X'
100 1.0583
200 3.012
300 1.79
--------------------------------------------------------------------------------
root='Z'
100 1.0633
200 7.6080000000000005
300 2.5220000000000002
--------------------------------------------------------------------------------