kicad/scripting/plugins/BomGeneration/optimize.py

74 lines
2.1 KiB
Python
Raw Normal View History

2022-04-08 21:49:19 -06:00
import pandas as pd
import numpy as np
score_method = "qty"
columns = [
"mpn",
"value",
"voltage_min",
"voltage_max",
"tolerance-",
"tolerance+",
]
parts = {
"C1": (None, 100e-9, 10, np.inf, None, None),
"C1a": (None, 100e-9, 10, 10, None, None),
"C2": (None, 100e-9, 16, np.inf, 0.20, 0.30),
"C2a": (None, 100e-9, 16, np.inf, None, None),
"C2b": (None, 100e-9, 12, np.inf, None, None),
"C3": (None, 100e-9, 0, np.inf, None, None),
"C4": (None, 10e-9, 10, np.inf, None, None),
"C5": (None, 10e-9, 12, np.inf, None, None),
}
nominal = pd.DataFrame(
[v for _, v in parts.items()],
index=parts.keys(),
columns=columns,
)
actual = nominal.copy(deep=True)
remaining = nominal.copy(deep=True)
# add temporary columns
remaining.insert(1, "matches", None, True)
remaining.insert(2, "score", -np.inf, True)
remaining.insert(3, "match_mpn", None, True)
# determine matches
for idx, row in remaining.iterrows():
matches = []
for ii, rr in remaining.iterrows():
if (ii == idx) or (
(rr["value"] == row["value"])
and (rr["voltage_min"] <= row["voltage_min"])
and (rr["voltage_max"] >= row["voltage_max"])
):
matches.append(ii)
remaining["matches"][idx] = matches
n = 0
while len(remaining.index) > 0:
for idx, row in remaining.iterrows():
if score_method == "qty":
# score by qty
remaining["score"][idx] = len(remaining["matches"][idx])
else:
# score by price reduction
pass
best_idx = remaining["score"].idxmax()
best_score = remaining["score"].max()
print(f"Step {n}: {best_idx} matched {len(remaining['matches'][best_idx]):d} parts (score: {best_score})")
for cmp in remaining["matches"][best_idx]:
if cmp in remaining.index:
actual.loc[cmp] = nominal.loc[best_idx]
# remove matched parts
remaining.drop(remaining["matches"][best_idx], inplace=True)
for idx in remaining.index:
remaining["matches"].loc[idx] = set(remaining["matches"][idx]).intersection(remaining.index)
n += 1