-
David Vronka authoredDavid Vronka authored
Generate_results_CSV.py 8.18 KiB
"""
Visualize results from the computation prepared by Generate_input_for_HQ.py
"""
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import os
import json
import sys
import argparse
import warnings
import re
# Copied from https://stackoverflow.com/questions/11150239/natural-sorting
def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split("([0-9]+)", key)]
return sorted(l, key=alphanum_key)
def generate_plot(df_best, vehicle_type_names, name_of_folder, number_of_iter):
df_best_extended = pd.DataFrame({})
how_many_vehicle_types = 0
for col in df_best.columns:
if "Vehicle Type" in col:
how_many_vehicle_types += 1
pd_index = 0
for row in range(len(df_best)):
for type in range(how_many_vehicle_types):
key_name = "Vehicle Type " + vehicle_type_names[type]
for add_row in range(df_best[key_name].iloc[row]):
df_row = pd.DataFrame(
{
"Problem Name": df_best["Problem Name"].iloc[row],
"Vehicle Type": key_name,
},
index=[pd_index],
)
pd_index += 1
df_best_extended = pd.concat([df_row, df_best_extended])
if df_best_extended.empty:
return
# df_best_extended.to_csv("df_best_extended.csv")
plt.clf()
plt.figure(figsize=(20, 12))
# number_of_colors = df_best_extended["Vehicle Type"].nunique()
pallete = {}
for i in range(len(vehicle_type_names)):
pallete.update(
{"Vehicle Type " + vehicle_type_names[i]: sns.color_palette()[i]}
)
chart = sns.histplot(
df_best_extended,
x="Problem Name",
hue="Vehicle Type",
multiple="dodge",
shrink=0.8,
palette=pallete,
)
sns.set(rc={"figure.figsize": (17, 10)})
ticks_loc = chart.get_xticks()
chart.xaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
chart.set_xticklabels(
chart.get_xticklabels(),
ha="center",
fontsize=14,
)
# mpl.rcParams["figure.figsize"] = 5, 25
# plt.show()
# plt.legend(title="Vehicles", labels=vehicle_type_names)
plt.savefig(
name_of_folder
+ "/plots_Problem_"
+ str(df_best["Problem Name"].iloc[0])
+ "_Fleet_"
+ str(df_best["Fleet Composition ID"].iloc[0])
+ ".png",
bbox_inches="tight",
)
plt.close()
return
def generate_full_results(
problem_name, used_fleet, vroom_output, df_final, fleet_index, given_index
):
"""Appending row to dataframe"""
served_all = "F"
if vroom_output["summary"]["unassigned"] == 0:
served_all = "T"
type_count = []
for add_zeros in range(len(used_fleet)):
type_count.append(0)
start_ind = 0
used_fleet = list(used_fleet.split(","))
used_fleet[0] = used_fleet[0].replace("[", "")
used_fleet[len(used_fleet) - 1] = used_fleet[len(used_fleet) - 1].replace("]", "")
for used in range(len(used_fleet)):
used_fleet[used] = int(used_fleet[used])
for type in range(len(type_count)):
for routes in vroom_output["routes"]:
if routes["vehicle"] == type + 1:
type_count[type] += 1
df_row = pd.DataFrame(
{
"Problem Name": problem_name,
"Fleet Composition ID": fleet_index + 1,
"Total Cost": [vroom_output["summary"]["cost"]],
"Total Duration": [vroom_output["summary"]["duration"]],
"Served All Shipments": served_all,
},
index=[given_index],
)
for fleet in range(len(used_fleet)):
vehicle_type = "Vehicle Type " + str(fleet + 1)
df_row[vehicle_type] = type_count[fleet]
df_final = pd.concat([df_final, df_row])
return df_final
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"-i",
"--inputfolder",
required=True,
help=("Path to input files. Usually output " "file of HyperQueue VROOM run."),
)
parser.add_argument(
"-o",
"--outputfolder",
default="output/results",
help="Path to output files. Defaults to output/results",
)
parser.add_argument(
"-r",
"--helperfolder",
default="output/vis_helper",
help=("Path to visualization helper files." "Created by Generate_input_for_HQ.py"),
)
args = parser.parse_args()
# Get environment variables
current_path = os.getcwd()
input_folder = os.path.join(current_path, args.inputfolder)
output_folder = os.path.join(current_path, args.outputfolder)
plots_folder = os.path.join(output_folder, "plots")
helper_folder = os.path.join(current_path, args.helperfolder)
if not os.path.exists(input_folder):
raise ValueError("Input folder given in --inputfolder does not exists.")
if not os.path.exists(helper_folder):
raise ValueError("Input folder given in --helperfolder does not exists.")
if not os.path.exists(output_folder):
os.mkdir(output_folder)
if not os.path.exists(plots_folder):
os.mkdir(plots_folder)
# Read helper files
file1 = open(os.path.join(helper_folder, "Used_fleets.txt"), "r")
data1 = file1.read()
used_fleets = data1.split("\n")
used_fleets.pop()
file2 = open(os.path.join(helper_folder, "Problem_names.txt"), "r")
data2 = file2.read()
problem_names = data2.split("\n")
problem_names.pop()
# used vehicle types
file3 = open(os.path.join(helper_folder, "Vehicle_names.txt"), "r")
data3 = file3.read()
vehicle_type_names = data3.split("\n")
vehicle_type_names.pop()
for vehicle_type in range(len(vehicle_type_names)):
vehicle_type_names[vehicle_type] = vehicle_type_names[vehicle_type].replace("'", "")
df_final = pd.DataFrame({})
# Read input json
list_of_files_unsorted = os.listdir(input_folder)
list_of_files_unsorted = [x for x in list_of_files_unsorted if ".json" in x]
if len(list_of_files_unsorted) == 1:
list_of_files = list_of_files_unsorted
elif len(list_of_files_unsorted) > 1:
list_of_files = natural_sort(list_of_files_unsorted)
else:
raise ValueError("No input JSON files found! Check --inputfolder argument")
list_of_vroom_results = []
for file in list_of_files:
json_file = open(input_folder + "/" + file, "r")
data = json_file.read()
json_file.close()
list_of_vroom_results.append(json.loads(data))
fleet_index = 0
given_index = 0
for fleet in used_fleets:
for problem in problem_names:
df_final = generate_full_results(
problem,
fleet,
list_of_vroom_results[given_index],
df_final,
fleet_index,
given_index,
)
given_index += 1
fleet_index += 1
# print(problem_names)
skip_these = []
df_best = pd.DataFrame({})
new_row = pd.DataFrame({})
# new_index = 0
for i in problem_names:
am_i_the_lowest = sys.maxsize
for j in range(len(df_final)):
if df_final["Problem Name"].iloc[j] in skip_these:
continue
if (
df_final["Total Cost"].iloc[j] < am_i_the_lowest
and df_final["Problem Name"].iloc[j] == i
and df_final["Served All Shipments"].iloc[j] == "T"
):
new_row = df_final.iloc[[j]]
am_i_the_lowest = df_final["Total Cost"].iloc[j]
skip_these.append(i)
if new_row.empty:
continue
df_best = pd.concat([df_best, new_row], ignore_index=True)
columns_to_rename = []
for col in df_final.columns:
if "Vehicle Type" in col:
columns_to_rename.append(col)
for x in range(len(columns_to_rename)):
df_final = df_final.rename(
columns={columns_to_rename[x]: "Vehicle Type " + vehicle_type_names[x]}
)
if df_best.empty:
continue
df_best = df_best.rename(
columns={columns_to_rename[x]: "Vehicle Type " + vehicle_type_names[x]}
)
df_best.to_csv(os.path.join(output_folder, "df_best.csv"))
df_final.to_csv(os.path.join(output_folder, "df_all.csv"))
number_of_iters = len(df_final)
for i in range(number_of_iters):
df_current = pd.DataFrame({})
df_current = df_final.loc[[i]]
df_current = df_current.reset_index(drop=True)
generate_plot(df_current, vehicle_type_names, os.path.join(plots_folder), i)