I want to find the number of unique panels I need to cover a number of openings that have a min and max value for their width and height:
It includes 5 inputs that are used to calculate the max and min width and height. I used ChatGPT for a potential solution, unfortunately this one runs forever and eventually times out.
Any hints are highly appreciated
The data frame that gets inputed looks like this :
enter image description here
import pandas as pd
import numpy as np
from itertools import product
from datetime import datetime
from google.colab import files
def optimize_panels(df, max_lr, min_lr, max_top, min_top, bot):
df['Widthmin'] = df['Width'] - 2 * max_lr
df['Widthmax'] = df['Width'] - 2 * min_lr
df['Heightmin'] = df['Height'] - 2 * max_top - bot
df['Heightmax'] = df['Height'] - 2 * min_top - bot
unique_ranges = df[['Widthmin', 'Widthmax', 'Heightmin', 'Heightmax']].drop_duplicates().reset_index(drop=True)
potential_panels = list(product(unique_ranges['Widthmin'].unique(), unique_ranges['Heightmin'].unique()))
coverage_matrix = np.zeros((len(unique_ranges), len(potential_panels)))
for i, range_row in unique_ranges.iterrows():
for j, panel in enumerate(potential_panels):
if range_row['Widthmin'] <= panel[0] <= range_row['Widthmax'] and range_row['Heightmin'] <= panel[1] <= range_row['Heightmax']:
coverage_matrix[i, j] = 1
def find_min_covering_panels(coverage_matrix):
covered = np.zeros(coverage_matrix.shape[0])
selected_panels = []
while not np.all(covered):
coverage_counts = coverage_matrix.T @ (1 - covered)
best_panel = np.argmax(coverage_counts)
selected_panels.append(best_panel)
covered = np.maximum(covered, coverage_matrix[:, best_panel])
return selected_panels
selected_panel_indices = find_min_covering_panels(coverage_matrix)
selected_panel_details = [potential_panels[idx] for idx in selected_panel_indices]
panel_to_number = {panel: idx + 1 for idx, panel in enumerate(selected_panel_details)}
def assign_panel_number(row, panel_mapping):
for panel, number in panel_mapping.items():
if row['Widthmin'] <= panel[0] <= row['Widthmax'] and row['Heightmin'] <= panel[1] <= row['Heightmax']:
return number, panel[0], panel[1]
return None, None, None
df['Panel Number'], df['Panel Width'], df['Panel Height'] = zip(*df.apply(lambda row: assign_panel_number(row, panel_to_number), axis=1))
df['Joint width'] = df['Width'] - df['Panel Width']
df['Joint height'] = df['Height'] - df['Panel Height']
df['Panel ID'] = range(1, len(df) + 1)
return df
def summarize_panels(df):
panel_summary = df.groupby('Panel Number').agg(
Usage_Count=('Panel Number', 'size'),
Panel_Width=('Panel Width', 'first'),
Panel_Height=('Panel Height', 'first')
).reset_index()
return panel_summary.sort_values('Usage_Count', ascending=False)
def main():
file_path = input("Enter the path to the CSV file: ")
df = pd.read_csv(file_path)
min_lr = float(input("Enter the minimum joint value left/right (fractional values allowed): "))
max_lr = float(input("Enter the maximum joint value left/right (fractional values allowed): "))
min_top = float(input("Enter the minimum joint value top (fractional values allowed): "))
max_top = float(input("Enter the maximum joint value top (fractional values allowed): "))
bot = float(input("Enter the bottom offset (fractional values allowed): "))
optimized_df = optimize_panels(df, max_lr, min_lr, max_top, min_top, bot)
panel_summary = summarize_panels(optimized_df)
optimized_df = optimized_df.round(3)
panel_summary = panel_summary.round(3)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
summary_filename = f"summary_{timestamp}.csv"
panels_filename = f"panels_{timestamp}.csv"
panel_summary.to_csv(summary_filename, index=False)
optimized_df[['Panel ID', 'Panel Number', 'Width', 'Height', 'Widthmin', 'Widthmax', 'Heightmin', 'Heightmax', 'Panel Width', 'Panel Height', 'Joint width', 'Joint height']].to_csv(panels_filename, index=False)
files.download(summary_filename)
files.download(panels_filename)
print("Optimization completed. Files are downloaded to your local machine.")
if __name__ == "__main__":
main()