Ejemplo n.º 1
0
def run_calculator_in_command_line():
    print(
        '--------- ** Run A Scientific Calculator Using Command Line ** ---------'
    )
    print(
        '** Enter the command "-h" or "help" to show available calculator functions...\n'
    )
    problem = Solver()
    global valid_answer_previous
    while True:
        infix = input('---> ')
        if infix in ['exit', 'quit']:
            break
        elif infix == 'ans':
            print(valid_answer_previous)
        elif infix in ["help", "-h"]:
            helper()
        else:
            try:
                temp_ans = problem.solve(infix)
                if temp_ans in errors:
                    print(temp_ans)
                else:
                    if isFloat(temp_ans):
                        temp_ans = float(temp_ans)
                    else:
                        temp_ans = integer_modification(temp_ans)
                    valid_answer_previous = temp_ans
                    print(temp_ans)
            except:
                print('Wrong Input')
Ejemplo n.º 2
0
    def evaluate(self, prob_id, tune=False, plot=True):
        assert prob_id in [1, 2, 3,
                           4], "Only support evaluation for problems1~4"

        self.prob_id = prob_id
        self.base_dir = osp.join(cfg.EVALUATION.ROOT_DIR,
                                 "prob" + str(prob_id))
        if not osp.exists(self.base_dir):
            os.makedirs(self.base_dir)
        self.strategy_path = osp.join(cfg.PROB.PROBLEM_LIST[prob_id - 1],
                                      "strategies.pkl")
        self.csv_path = self.strategy_path[:-3] + "csv"
        self.hub_path = osp.join(osp.dirname(self.strategy_path), "hubs.pkl")
        if not tune and not osp.exists(self.strategy_path):
            key = input(
                "It seems that you have not run solver for this problem yet. Run Now?(y or n)"
            )
            if key == 'Y' or key == 'y':
                solver = Solver()
                solver.solve(problem_id=prob_id)
            else:
                print("exit")
                return

        if osp.exists(self.strategy_path):
            self._pkl2csv()
            avg_amount_cost, avg_time_cost = self.get_avg_cost()
            print(
                "For problem {}:\nAverage amount cost:{:.2f} | Average time cost: {:.2f}min"
                .format(prob_id, avg_amount_cost, avg_time_cost))

        # whether we are tuning the parameters
        if tune:
            if prob_id == 1:
                # for problem1 we tune the weight_amount and weight_cost
                # self.weight_tune()
                self.weight_plot()
            elif prob_id == 2:
                # self.hub_cost_test()
                self.hub_cost_plot()
            elif prob_id == 3:
                # self.hub_cap_test()
                self.hub_cap_plot()

        # plot the distribution or not
        if plot:
            self.plot_distribution()
Ejemplo n.º 3
0
    def hub_cap_test(self):
        hub_cap_path = osp.join(self.base_dir, "cap.csv")

        index = np.where(
            cfg.EVALUATION.HUB_CAPACITY_FIELD == cfg.PARAM.HUB_CAPACITY)[0]
        hub_capacity_field = np.insert(cfg.EVALUATION.HUB_CAPACITY_FIELD,
                                       index, 0.95 * cfg.PARAM.HUB_CAPACITY)
        hub_capacity_field = np.insert(hub_capacity_field, index + 2,
                                       1.05 * cfg.PARAM.HUB_CAPACITY)

        new_dict = edict()
        num_hubs_list, amount_cost_list, time_cost_list = [], [], []
        mask = np.ones_like(hub_capacity_field)
        for idx, cap in enumerate(hub_capacity_field):
            new_dict["HUB_CAPACITY"] = cap
            merge_a_into_b(new_dict, cfg)
            solver = Solver()
            solver.solve(problem_id=3, tune_mode=True)
            with open(self.hub_path, "rb") as f:
                data = pkl.load(f)
                num_hubs = len(data["hubs"])
            if num_hubs == 0:
                print("When capacity is :{}. No hubs were built...Continue...".
                      format(cap))
                mask[idx] = 0
                continue
            self._pkl2csv()
            avg_amount_cost, avg_time_cost = self.get_avg_cost()
            amount_cost_list.append(avg_amount_cost)
            time_cost_list.append(avg_time_cost)
            num_hubs_list.append(num_hubs)
            print(
                "Hub capacity: {:.0f} | Hubs: {:.0f} | Average amount cost: {:.3f}$ | Average time cost: {:.2f}m."
                .format(cap, num_hubs, avg_amount_cost, avg_time_cost))
        df = pd.DataFrame(
            data=list(
                zip(hub_capacity_field[np.nonzero(mask)], num_hubs_list,
                    amount_cost_list, time_cost_list)),
            columns=["HubCapacity", "NumHubs", "AmountCost", "TimeCost"])
        df["Products"] = df["AmountCost"] * df["TimeCost"]
        df["Values"] = cfg.PARAM.WEIGHT_AMOUNT * df[
            "AmountCost"] + cfg.PARAM.WEIGHT_TIME * df["TimeCost"]
        df.to_csv(hub_cap_path, index=False, float_format="%.2f")
Ejemplo n.º 4
0
    def weight_tune(self):
        """ tuning the weight of time and weight of cost
        """
        new_dict = edict()
        weight_data_path = osp.join(self.base_dir, "weight.csv")
        weight_time_list, weight_amount_list = [], []
        amount_cost_list, time_cost_list = [], []
        for weight_amount in cfg.EVALUATION.WEIGHT_AMOUNT_FIELD:
            for weight_time in cfg.EVALUATION.WEIGHT_TIME_FIELD:
                new_dict["WEIGHT_AMOUNT"] = round(weight_amount, 2)
                new_dict["WEIGHT_TIME"] = round(weight_time, 2)
                # merge the config
                merge_a_into_b(new_dict, cfg)
                # solve the problem and get the output
                solver = Solver()
                solver.solve(problem_id=1, tune_mode=True)
                # don't forget transform into csv file
                self._pkl2csv()
                avg_amount_cost, avg_time_cost = self.get_avg_cost()
                weight_amount_list.append(round(weight_amount, 2))
                weight_time_list.append(round(weight_time, 2))
                amount_cost_list.append(avg_amount_cost)
                time_cost_list.append(avg_time_cost)
                print(
                    "When weight of amount is {:.2f} and weight of time is:{:.2f}"
                    .format(weight_amount, weight_time))
                print(
                    "Average amount cost is: {:.1f}. Average time cost is:{:.1f}"
                    .format(avg_amount_cost, avg_time_cost))

        df = pd.DataFrame(data=list(
            zip(weight_amount_list, weight_time_list, amount_cost_list,
                time_cost_list)),
                          columns=[
                              "WeightOfAmount", "WeightOfTime", "AmountCost",
                              "TimeCost"
                          ])
        # multiply the two columns to get the products
        df["Products"] = df["AmountCost"] * df["TimeCost"]
        df.to_csv(weight_data_path, index=False, float_format="%.2f")
Ejemplo n.º 5
0
def get_answer(expression):
    problem = Solver()
    try:
        temp_ans = problem.solve(expression)
        if temp_ans in errors:
            return str(temp_ans)
        else:
            global valid_answer_previous
            if isFloat(temp_ans):
                temp_ans = float(temp_ans)
            else:
                temp_ans = integer_modification(temp_ans)
            valid_answer_previous = temp_ans
            return str(temp_ans)
    except:
        return 'Wrong Input'
Ejemplo n.º 6
0
                    help="the number of orders to parse", type=int, default=2400)
parser.add_argument("--process_num", dest="NUM_PROCESSES",
                    help="the number of processes", type=int, default=16)
parser.add_argument("--weight_amount", dest="WEIGHT_AMOUNT",
                    help="the weight of the amountCost in the objective function", type=float, default=15)
parser.add_argument("--weight_time", dest="WEIGHT_TIME",
                    help="the weight of the timeCost in the objective function", type=float, default=1)
parser.add_argument("--hub_cost_const", dest="HUB_BUILT_COST_CONST",
                    help="the constant part of cost of building a hub", type=int, default=3000)
parser.add_argument("--hub_cost_vary", dest="HUB_BUILT_COST_VARY",
                    help="the variable part cost of building a hub", type=float, default=2.0)
parser.add_argument("--hub_ratio", dest="HUB_UNIT_COST_RATIO",
                    help="the cutoff of unit price of a hub", type=float, default=0.7)
parser.add_argument("--hub_capacity", dest="HUB_CAPACITY",
                    help="the capacity of the hub(in prob3)", type=int, default=500)

args = parser.parse_args()

arg_dict = edict(vars(args))
merge_a_into_b(arg_dict, cfg)
print("Using the config:")
print(cfg)

solver = Solver()
evaluator = Evaluator()

solver.solve(problem_id=args.PROBLEM_ID)
# disable the tune mode but plot the distribution, see the outputs for more detail
evaluator.evaluate(prob_id=args.PROBLEM_ID, tune=False, plot=True)

Ejemplo n.º 7
0
import sys
from src.solver import Solver
from src.parsing import parse

lines = []
for line in sys.stdin:
    lines.append(line.rstrip('\n'))

matrix = parse()
solver = Solver(matrix)
# print(matrix)
# print(solver.is_solved(matrix))
# print(solver.manhattan_distance(matrix))
print(solver.solve(matrix))
Ejemplo n.º 8
0
    def hub_cost_test(self):
        """ sensitivity check for parameters cfg.PARAM.HUB_BUILT_COST_VARY
        cfg.PARAM.HUB_BUILT_COST_CONST, cfg.PARAM.HUB_BUILT_COST_RATIO
        """
        cost_vary_path = osp.join(self.base_dir, "vary.csv")
        cost_const_path = osp.join(self.base_dir, "const.csv")
        cost_ratio_path = osp.join(self.base_dir, "ratio.csv")

        new_dict = edict()
        ori_ratio, ori_const_cost, ori_vary_cost = cfg.PARAM.HUB_UNIT_COST_RATIO, \
            cfg.PARAM.HUB_BUILT_COST_CONST, cfg.PARAM.HUB_BUILT_COST_VARY

        num_hubs_list, amount_cost_list, time_cost_list = [], [], []
        # insert some values around the default values
        index = np.where(cfg.EVALUATION.HUB_RATIO_FIELD == ori_ratio)[0]
        hub_ratio_field = np.insert(cfg.EVALUATION.HUB_RATIO_FIELD, index,
                                    round(0.95 * ori_ratio, 2))
        hub_ratio_field = np.insert(hub_ratio_field, index + 2,
                                    round(1.05 * ori_ratio, 2))
        print("HUB_RATIO_FIELD : ", hub_ratio_field)
        mask = np.ones_like(hub_ratio_field)
        for idx, ratio in enumerate(hub_ratio_field):
            new_dict["HUB_UNIT_COST_RATIO"] = ratio
            merge_a_into_b(new_dict, cfg)
            solver = Solver()
            solver.solve(problem_id=2, tune_mode=True)
            with open(self.hub_path, "rb") as f:
                num_hubs = len(pkl.load(f))
            if num_hubs == 0:
                print(
                    "When ratio is: {}. Some error has occurred... Maybe no hubs were built."
                    .format(ratio))
                mask[idx] = 0
                continue
            self._pkl2csv()
            # get the number of hubs
            avg_amount_cost, avg_time_cost = self.get_avg_cost()
            amount_cost_list.append(avg_amount_cost)
            time_cost_list.append(avg_time_cost)
            num_hubs_list.append(num_hubs)
            print(
                "Ratio: {:.2f} | Hubs: {:.0f} | Average amount cost:{:.2f}$ | Average time cost:{:.2f}m."
                .format(ratio, num_hubs, avg_amount_cost, avg_time_cost))
        # save to csv
        df = pd.DataFrame(
            data=list(
                zip(hub_ratio_field[np.nonzero(mask)], num_hubs_list,
                    amount_cost_list, time_cost_list)),
            columns=["Ratio", "NumHubs", "AmountCost", "TimeCost"])
        df["Products"] = df["AmountCost"] * df["TimeCost"]
        df["Values"] = cfg.PARAM.WEIGHT_AMOUNT * df[
            "AmountCost"] + cfg.PARAM.WEIGHT_TIME * df["TimeCost"]
        df.to_csv(cost_ratio_path, index=False, float_format="%.2f")

        # reset to default value
        new_dict["HUB_UNIT_COST_RATIO"] = ori_ratio
        index = np.where(
            cfg.EVALUATION.HUB_COST_CONST_FIELD == ori_const_cost)[0]
        hub_const_field = np.insert(cfg.EVALUATION.HUB_COST_CONST_FIELD, index,
                                    0.95 * ori_const_cost)
        hub_const_field = np.insert(hub_const_field, index + 2,
                                    1.05 * ori_const_cost)

        # then check the sensitivity of the HUB_BUILT_COST_CONST
        # add exception handler for fear of no hubs
        num_hubs_list, amount_cost_list, time_cost_list = [], [], []
        mask = np.ones_like(hub_const_field)
        for idx, const_cost in enumerate(hub_const_field):
            new_dict["HUB_BUILT_COST_CONST"] = const_cost
            merge_a_into_b(new_dict, cfg)
            solver = Solver()
            solver.solve(problem_id=2, tune_mode=True)
            with open(self.hub_path, "rb") as f:
                num_hubs = len(pkl.load(f))
            if num_hubs == 0:
                print("When const cost is :{}. No hubs are built. Continue...".
                      format(const_cost))
                mask[idx] = 0
                continue
            self._pkl2csv()
            # get the number of hubs
            avg_amount_cost, avg_time_cost = self.get_avg_cost()
            amount_cost_list.append(avg_amount_cost)
            time_cost_list.append(avg_time_cost)
            num_hubs_list.append(num_hubs)
            print(
                "Const cost: {:.0f} | Hubs: {:.0f} | Average amount cost: {:.2f}$ | Average time cost: {:.2f}m."
                .format(const_cost, num_hubs, avg_amount_cost, avg_time_cost))
        df = pd.DataFrame(
            data=list(
                zip(hub_const_field[np.nonzero(mask)], num_hubs_list,
                    amount_cost_list, time_cost_list)),
            columns=["HubConstCost", "NumHubs", "AmountCost", "TimeCost"])
        df["Products"] = df["AmountCost"] * df["TimeCost"]
        df["Values"] = cfg.PARAM.WEIGHT_AMOUNT * df[
            "AmountCost"] + cfg.PARAM.WEIGHT_TIME * df["TimeCost"]
        df.to_csv(cost_const_path, index=False, float_format="%.2f")

        # reset the const part to default value
        new_dict["HUB_BUILT_COST_CONST"] = ori_const_cost

        index = np.where(
            cfg.EVALUATION.HUB_COST_VARY_FIELD == ori_vary_cost)[0]
        hub_vary_field = np.insert(cfg.EVALUATION.HUB_COST_VARY_FIELD, index,
                                   0.95 * ori_vary_cost)
        hub_vary_field = np.insert(hub_vary_field, index + 2,
                                   1.05 * ori_vary_cost)

        # check the sensitivity of the HUB_BUILT_COST_VARY
        num_hubs_list, amount_cost_list, time_cost_list = [], [], []
        mask = np.ones_like(hub_vary_field)
        for idx, vary_cost in enumerate(hub_vary_field):
            new_dict["HUB_BUILT_COST_VARY"] = vary_cost
            merge_a_into_b(new_dict, cfg)
            solver = Solver()
            solver.solve(problem_id=2, tune_mode=True)
            with open(self.hub_path, "rb") as f:
                num_hubs = len(pkl.load(f))
            if num_hubs == 0:
                print("When vary cost is :{}. No hubs are built. Continue..".
                      format(vary_cost))
                mask[idx] = 0
                continue
            self._pkl2csv()
            avg_amount_cost, avg_time_cost = self.get_avg_cost()
            amount_cost_list.append(avg_amount_cost)
            time_cost_list.append(avg_time_cost)
            num_hubs_list.append(num_hubs)
            print(
                "Vary cost: {:.0f} | Hubs: {:.0f} | Average amount cost: {:.3f}$ | Average time cost: {:.2f}m."
                .format(vary_cost, num_hubs, avg_amount_cost, avg_time_cost))
        df = pd.DataFrame(
            data=list(
                zip(hub_vary_field[np.nonzero(mask)], num_hubs_list,
                    amount_cost_list, time_cost_list)),
            columns=["HubVaryCost", "NumHubs", "AmountCost", "TimeCost"])
        df["Products"] = df["AmountCost"] * df["TimeCost"]
        df["Values"] = cfg.PARAM.WEIGHT_AMOUNT * df[
            "AmountCost"] + cfg.PARAM.WEIGHT_TIME * df["TimeCost"]
        df.to_csv(cost_vary_path, index=False, float_format="%.2f")
        # reset
        new_dict["HUB_BUILT_COST_VARY"] = ori_vary_cost
        merge_a_into_b(new_dict, cfg)
Ejemplo n.º 9
0
from src.solver import Solver

s = Solver()
s.solve()
print(s)
Ejemplo n.º 10
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.data = DataStore()
        self.truck_states = {}
        self.update_data_table()
        self.number_of_iterations = 100
        self.setup_data()
        self.connections()
        self.results = {}
        self.combobox_coming_sequence = []
        self.combobox_going_sequence = []
        self.statusBar().showMessage("Ready")
        self.setup_sequence_solver()
        self.load_generated_data()
        self.graphicsView.data = self.data
        self.setup_simulator()
        self.graphicsView.parent = self
        self.showing_result = []
        self.result_times = {}
        self.function_type = "normal"

    def setup_data(self):
        self.data_set_model = DataSetModel(self.data)
        self.datasettable.setModel(self.data_set_model)
        self.inbound_table_model = GoodTableModel(
            self.data.number_of_inbound_trucks, self.data.number_of_goods, self.data.inbound_goods, "inbound"
        )
        self.inbound_good_table.setModel(self.inbound_table_model)
        self.outbound_table_model = GoodTableModel(
            self.data.number_of_outbound_trucks, self.data.number_of_goods, self.data.outbound_goods, "outbound"
        )
        self.outbound_good_table.setModel(self.outbound_table_model)
        self.compound_coming_table_model = GoodTableModel(
            self.data.number_of_compound_trucks,
            self.data.number_of_goods,
            self.data.compound_coming_goods,
            "compound_coming",
        )
        self.compound_coming_good_table.setModel(self.compound_coming_table_model)
        self.compound_going_table_model = GoodTableModel(
            self.data.number_of_compound_trucks,
            self.data.number_of_goods,
            self.data.compound_going_goods,
            "compound_going",
        )
        self.compound_going_good_table.setModel(self.compound_going_table_model)

        self.numberOfIterationsLineEdit.setText(str(self.number_of_iterations))

    def generate_times(self):
        self.data.arrival_times = []
        self.data.lower_boundaries = []
        self.data.upper_boundaries = []
        for k, data_set in enumerate(self.data.data_sets):
            self.data.arrival_times.append({})
            self.data.lower_boundaries.append({})
            self.data.upper_boundaries.append({})

            self.data.calculate_truck_related_data()
            for i in range(self.data.number_of_inbound_trucks):
                name = "inbound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.coming_mu, self.data.product_per_coming_truck)
                self.data.arrival_times[k][name] = int(uniform(self.data.inbound_arrival_time, two_gdj))

            for i in range(self.data.number_of_outbound_trucks):
                name = "outbound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.going_mu, self.data.product_per_going_truck)
                gdj = int(uniform(self.data.outbound_arrival_time, two_gdj))
                self.data.arrival_times[k][name] = gdj
                A = (
                    gdj
                    + (self.data.going_mu - 1) * self.data.changeover_time
                    + self.data.going_mu * self.data.product_per_going_truck * self.data.loading_time
                )
                self.data.lower_boundaries[k][name] = int(A * data_set[0])
                self.data.upper_boundaries[k][name] = int(A * data_set[1])

            for i in range(self.data.number_of_compound_trucks):
                name = "compound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.coming_mu, self.data.product_per_coming_truck)
                gdj = int(uniform(self.data.outbound_arrival_time, two_gdj))
                self.data.arrival_times[k][name] = gdj
                # A = gdj + (self.data.going_mu - 1) * self.data.changeover_time + self.data.going_mu * self.data.product_per_going_truck * self.data.loading_time
                A = (
                    gdj
                    + (self.data.coming_mu - 1) * self.data.changeover_time
                    + self.data.coming_mu * self.data.product_per_coming_truck * self.data.loading_time
                    + self.data.changeover_time
                    + self.data.truck_transfer_time
                    + (self.data.going_mu - 1) * self.data.changeover_time
                    + self.data.going_mu * self.data.product_per_going_truck * self.data.loading_time
                )
                self.data.lower_boundaries[k][name] = int(A * data_set[0])
                self.data.upper_boundaries[k][name] = int(A * data_set[1])
        self.load_generated_data()

    def new_generate_times(self):
        self.data.arrival_times = []
        self.data.lower_boundaries = []
        self.data.upper_boundaries = []
        for k, data_set in enumerate(self.data.data_sets):
            self.data.arrival_times.append({})
            self.data.lower_boundaries.append({})
            self.data.upper_boundaries.append({})

            self.data.calculate_truck_related_data()
            for i in range(self.data.number_of_inbound_trucks):
                name = "inbound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.coming_mu, self.data.product_per_coming_truck)
                self.data.arrival_times[k][name] = int(uniform(self.data.inbound_arrival_time, two_gdj))

            for i in range(self.data.number_of_outbound_trucks):
                name = "outbound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.going_mu, self.data.product_per_going_truck)
                gdj = int(uniform(self.data.outbound_arrival_time, two_gdj))
                self.data.arrival_times[k][name] = gdj
                A = (
                    self.data.product_per_coming_truck * self.data.unloading_time
                    + gdj
                    + self.data.product_per_going_truck * self.data.loading_time
                )
                self.data.lower_boundaries[k][name] = int(A * data_set[0])
                self.data.upper_boundaries[k][name] = int(A * data_set[1])

            for i in range(self.data.number_of_compound_trucks):
                name = "compound" + str(i)
                two_gdj = self.calculate_2dgj(data_set[2], self.data.coming_mu, self.data.product_per_coming_truck)
                gdj = int(uniform(self.data.outbound_arrival_time, two_gdj))
                self.data.arrival_times[k][name] = gdj
                A = (
                    self.data.product_per_coming_truck * self.data.unloading_time
                    + gdj
                    + self.data.product_per_going_truck * self.data.loading_time
                )
                self.data.lower_boundaries[k][name] = int(A * data_set[0])
                self.data.upper_boundaries[k][name] = int(A * data_set[1])
        self.load_generated_data()

    def load_generated_data(self):
        self.arrival_time_table_model = TimeTableModel(self.data.arrival_times)
        self.arrival_time_table.setModel(self.arrival_time_table_model)
        self.leaving_lower_table_model = TimeTableModel(self.data.lower_boundaries)
        self.leaving_lower_table.setModel(self.leaving_lower_table_model)
        self.leaving_upper_table_model = TimeTableModel(self.data.upper_boundaries)
        self.leaving_upper_table.setModel(self.leaving_upper_table_model)

    def calculate_2dgj(self, tightness_factor, mu, product_per_truck):
        return (2 * mu * tightness_factor * product_per_truck) / (2 - tightness_factor * mu * self.data.makespan_factor)

    def connections(self):
        """
        create connections from buttons to functions
        :return:
        """
        self.value_connections()

        self.numberOfInboundTrucksSpinBox.valueChanged.connect(self.set_inbound_truck_number)
        self.numberOfOutboundTrucksSpinBox.valueChanged.connect(self.set_outbound_truck_number)
        self.numberOfCompoundTrucksSpinBox.valueChanged.connect(self.set_compound_truck_number)
        self.numberOfCompoundTrucksSpinBox.valueChanged.connect(self.set_compound_truck_number)
        self.numberOfShippingDoorsSpinBox.valueChanged.connect(self.set_shipping_door_number)
        self.numberOfReceivingDoorsSpinBox.valueChanged.connect(self.set_receiving_door_number)
        self.numberOfGoodsSpinBox.valueChanged.connect(self.update_number_of_goods)

        self.print_gams.clicked.connect(self.gams_output)
        self.stop_data_set_solve_button.clicked.connect(self.stop)

        self.solve_data_set_button.clicked.connect(self.solve_data_set)
        self.solve_one_sequence_button.clicked.connect(self.solve_one_sequence)
        self.actionNew_Data.triggered.connect(self.new_data)
        self.actionSave_Data.triggered.connect(self.save_data)
        self.actionLoad_Data.triggered.connect(self.load_data)
        self.pause_button.clicked.connect(self.pause)
        self.resume_button.clicked.connect(self.resume)
        self.generate_times_button.clicked.connect(self.generate_times)
        self.generate_new_boundaries_button.clicked.connect(self.new_generate_times)
        self.stop_button.clicked.connect(self.finished)

        self.result_names_combo_box.currentTextChanged.connect(self.change_result_name)
        self.show_results_button.clicked.connect(self.show_results)

    def new_data(self):
        self.data = DataStore()
        self.update_data_table()
        self.value_connections()
        self.setup_data()

    def value_connections(self):
        self.numberOfDataSetsSpinBox.valueChanged.connect(self.set_data_set_table)
        self.loadingTumeLineEdit.textChanged.connect(self.data.set_loading_time)
        self.unloading_time_edit.textChanged.connect(self.data.set_unloading_time)
        self.truckChangeoverTimeLineEdit.textChanged.connect(self.data.set_changeover_time)
        self.effectOfTheArrivalTimesOnMakespanLineEdit.textChanged.connect(self.data.set_makespan_factor)
        self.truckTransferTimeLineEdit.textChanged.connect(self.data.set_truck_transfer_time)
        self.inboundArrivalTimeLineEdit.textChanged.connect(self.data.set_inbound_arrival_time)
        self.outboundArrivalTimeLineEdit.textChanged.connect(self.data.set_outbound_arrival_time)
        self.goodTransferTimeLineEdit.textChanged.connect(self.data.set_good_transfer_time)

    def set_inbound_truck_number(self, value):
        self.inbound_table_model.truck_number(value)
        self.data.number_of_inbound_trucks = value
        self.data.update_truck_numbers()
        self.setup_sequence_solver()

    def set_outbound_truck_number(self, value):
        self.outbound_table_model.truck_number(value)
        self.data.number_of_outbound_trucks = value
        self.data.update_truck_numbers()
        self.setup_sequence_solver()

    def set_compound_truck_number(self, value):
        self.compound_coming_table_model.truck_number(value)
        self.compound_going_table_model.truck_number(value)
        self.data.number_of_compound_trucks = value
        self.data.update_truck_numbers()
        self.setup_sequence_solver()

    def set_receiving_door_number(self, value):
        self.data.set_receiving_door_number(value)
        self.setup_sequence_solver()
        self.setup_simulator()

    def set_shipping_door_number(self, value):
        self.data.set_shipping_door_number(value)
        self.setup_sequence_solver()
        self.setup_simulator()

    def update_data_table(self):
        """
        update table values
        :return:
        """
        self.loadingTumeLineEdit.setText(str(self.data.loading_time))
        try:
            self.unloading_time_edit.setText(str(self.data.unloading_time))
        except:
            self.unloading_time_edit.setText(str(0))
            self.data.unloading_time = 0
        self.truckChangeoverTimeLineEdit.setText(str(self.data.changeover_time))
        self.effectOfTheArrivalTimesOnMakespanLineEdit.setText(str(self.data.makespan_factor))
        self.truckTransferTimeLineEdit.setText(str(self.data.truck_transfer_time))
        self.inboundArrivalTimeLineEdit.setText(str(self.data.inbound_arrival_time))
        self.outboundArrivalTimeLineEdit.setText(str(self.data.outbound_arrival_time))
        self.goodTransferTimeLineEdit.setText(str(self.data.good_transfer_time))
        self.numberOfInboundTrucksSpinBox.setValue(self.data.number_of_inbound_trucks)
        self.numberOfOutboundTrucksSpinBox.setValue(self.data.number_of_outbound_trucks)
        self.numberOfCompoundTrucksSpinBox.setValue(self.data.number_of_compound_trucks)
        self.numberOfReceivingDoorsSpinBox.setValue(self.data.number_of_receiving_doors)
        self.numberOfShippingDoorsSpinBox.setValue(self.data.number_of_shipping_doors)
        self.numberOfGoodsSpinBox.setValue(self.data.number_of_goods)
        self.numberOfDataSetsSpinBox.setValue(self.data.number_of_data_sets)

    def update_number_of_goods(self, amount):
        self.inbound_table_model.change_good_number(amount)
        self.outbound_table_model.change_good_number(amount)
        self.compound_coming_table_model.change_good_number(amount)
        self.compound_going_table_model.change_good_number(amount)
        self.data.number_of_goods = amount

    def set_data_set_table(self):
        self.data.number_of_data_sets = self.numberOfDataSetsSpinBox.value()
        if self.numberOfDataSetsSpinBox.value() > len(self.data_set_model.data):
            self.data_set_model.insertRows(len(self.data_set_model.data), self.numberOfDataSetsSpinBox.value())
        elif self.numberOfDataSetsSpinBox.value() < len(self.data_set_model.data):
            self.data_set_model.removeRows(len(self.data_set_model.data), self.numberOfDataSetsSpinBox.value())

    def load_data(self):
        """
        loads prev saved data
        :return:
        """
        file_name, _ = QFileDialog.getOpenFileName(self, "Open file", "/home")
        try:
            self.data = pickle.load(open(file_name, "rb"))
        except Exception as e:
            pass
        self.graphicsView.data = self.data
        self.setup_data()
        self.update_data_table()
        self.load_generated_data()
        self.value_connections()

    def save_data(self):
        """
        saves current data
        :return:
        """
        self.graphicsView.data = self.data
        self.setup_data()
        file_name, _ = QFileDialog.getSaveFileName(self, "Save file", "/home")
        try:
            pickle.dump(self.data, open(file_name, "wb"))
        except Exception as e:
            pass

    def setup_sequence_solver(self):
        self.combobox_coming_sequence = []
        self.combobox_going_sequence = []
        self.setup_truck_names()
        self.coming_truck_list = self.data.coming_truck_name_list + ["0"] * (self.data.number_of_receiving_doors - 1)
        self.going_truck_list = self.data.going_truck_name_list + ["0"] * (self.data.number_of_shipping_doors - 1)

        for i in range(self.data.number_of_coming_trucks + self.data.number_of_receiving_doors - 1):
            newbox = QComboBox()
            newbox.addItems(self.coming_truck_list)
            self.combobox_coming_sequence.append(newbox)

        for i in range(self.data.number_of_going_trucks + self.data.number_of_shipping_doors - 1):
            newbox = QComboBox()
            newbox.addItems(self.going_truck_list)
            self.combobox_going_sequence.append(newbox)

        for i, box in enumerate(self.combobox_coming_sequence):
            self.sequence_grid.addWidget(box, 0, i)

        for i, box in enumerate(self.combobox_going_sequence):
            self.sequence_grid.addWidget(box, 1, i)

    def setup_truck_names(self):

        GoodStore.loading_time = self.data.loading_time
        Door.good_transfer_time = self.data.good_transfer_time
        self.data.truck_name_list = []
        self.data.coming_truck_name_list = []
        self.data.going_truck_name_list = []
        for i in range(self.data.number_of_inbound_trucks):
            name = "inbound" + str(i)
            self.data.truck_name_list.append(name)
            self.data.coming_truck_name_list.append(name)
            self.truck_states[name] = "coming"
        for i in range(self.data.number_of_outbound_trucks):
            name = "outbound" + str(i)
            self.data.truck_name_list.append(name)
            self.data.going_truck_name_list.append(name)
            self.truck_states[name] = "coming"
        for i in range(self.data.number_of_compound_trucks):
            name = "compound" + str(i)
            self.data.truck_name_list.append(name)
            self.data.coming_truck_name_list.append(name)
            self.data.going_truck_name_list.append(name)
            self.truck_states[name] = "coming"

    def update_truck_numbers(self):
        self.data.update_truck_numbers()

    def solve_data_set(self):
        self.start_time = time.time()

        self.annealing = Annealing(
            self.data, int(self.tempereature_line_edit.text()), float(self.decav_factor_line_edit.text())
        )
        self.tabu = Tabu(
            self.data, int(self.number_of_tabu_line_edit.text()), int(self.number_of_tabu_neighbours_line_edit.text())
        )
        self.algorithms = {"annealing": self.annealing, "tabu": self.tabu}
        self.algorithm_name = str(self.solverComboBox.currentText())
        self.function_type = str(self.function_combo_box.currentText())
        self.algorithm = self.algorithms[self.algorithm_name]
        self.update_truck_numbers()

        self.data_set_number = self.data_set_spin_box.value() - 1
        self.iteration_number = 0
        self.number_of_iterations = int(self.numberOfIterationsLineEdit.text())
        self.setup_truck_names()

        self.slow_solution = not self.fast_solve_check_box.isChecked()

        if self.slow_solution:
            self.solution_name = "data_set_{0}_{1}_{2}_{3}".format(
                self.data_set_number + 1,
                self.solverComboBox.currentText(),
                self.function_combo_box.currentText(),
                len(self.results) + 1,
            )
            self.results[self.solution_name] = []
            self.result_names_combo_box.addItem(self.solution_name)

            self.coming_sequence_table_model = SequenceTableModel(self.results[self.solution_name], 0, self.data)
            self.coming_sequence_table.setModel(self.coming_sequence_table_model)

            self.going_sequence_table_model = SequenceTableModel(self.results[self.solution_name], 1, self.data)
            self.going_sequence_table.setModel(self.going_sequence_table_model)

            if self.algorithm_name == "annealing":
                self.error_sequence_table_model = AnnealingErrorTableModel(self.results[self.solution_name], self.data)
                self.sequence_error_table.setModel(self.error_sequence_table_model)

            elif self.algorithm_name == "tabu":
                self.error_sequence_table_model = TabuErrorTableModel(self.results[self.solution_name], self.data)
                self.sequence_error_table.setModel(self.error_sequence_table_model)

        self.next_iteration()

    def save_results(self):
        self.current_result_data = ResultData(self.data)
        self.current_result_data.times = copy.deepcopy(self.result_times)
        self.sequence.error = self.calculate_error()
        self.current_result_data.sequence = copy.deepcopy(self.sequence)
        self.current_result_data.goods = self.solver.return_goods()
        self.result_times = {}
        self.results[self.solution_name].append(self.current_result_data)
        self.coming_sequence_table_model.insertRows(0, 0)
        self.going_sequence_table_model.insertRows(0, 0)
        self.error_sequence_table_model.insertRows(0, 0)

    def save_tabu_results(self):
        self.current_result_data = ResultData(self.data)
        self.current_result_data.times = {}
        self.sequence.error = float("inf")
        self.current_result_data.sequence = copy.deepcopy(self.sequence)
        self.current_result_data.goods = {}
        self.result_times = {}
        self.results[self.solution_name].append(self.current_result_data)
        self.coming_sequence_table_model.insertRows(0, 0)
        self.going_sequence_table_model.insertRows(0, 0)
        self.error_sequence_table_model.insertRows(0, 0)

    def next_iteration(self):
        print("next")
        try:
            self.solver = Solver(self.data_set_number, self.data)
            self.solver.done_signal.connect(self.iteration_end)
            self.solver.value_signal.connect(self.time_saver)
            print(self.iteration_number)
            if self.iteration_number == 0:

                self.sequence = copy.deepcopy(self.algorithm.start1())
                self.iteration_number += 1
                self.solver.set_sequence(self.sequence)
                self.solver.solve()

            elif self.iteration_number < self.number_of_iterations + 1:
                if self.algorithm_name == "annealing":

                    new_sequence = self.algorithm.next_iteration(self.sequence, self.iteration_number)
                    if self.slow_solution:
                        self.current_result_data.sequence = copy.deepcopy(self.sequence)
                    self.iteration_number += 1
                    self.sequence = new_sequence
                    self.solver.set_sequence(self.sequence)
                    self.solver.solve()

                elif self.algorithm_name == "tabu":
                    print("tabu")
                    if self.algorithm.generated_neighbour_number == self.algorithm.number_of_neighbours:
                        print("if")
                        self.algorithm.generated_neighbour_number = 0
                        decision_list = self.algorithm.choose_sequence()
                        # if self.slow_solution:
                        for i, decision in enumerate(decision_list):
                            self.results[self.solution_name][-len(decision_list) + i].sequence.values[
                                "decision"
                            ] = decision
                        self.iteration_number += 1
                        self.next_iteration()
                    else:
                        new_sequence = self.algorithm.next_iteration(self.iteration_number)
                        self.sequence = new_sequence
                        self.algorithm.generated_neighbour_number += 1
                        if self.algorithm.check_tabu(self.sequence):
                            self.save_tabu_results()
                            self.next_iteration()
                        else:
                            self.solver.set_sequence(self.sequence)
                            self.solver.solve()

            elif self.iteration_number == self.number_of_iterations + 1:
                self.end_time = time.time()
                self.solution_time = self.end_time - self.start_time
                self.solution_time_label.setText(str(int(self.solution_time)))
                self.stop()
        except:
            pass

    def check_iteration_finish(self):
        pass

    def iteration_end(self):
        print("end")
        try:
            self.save_results()
            if self.algorithm_name == "annealing":
                self.solver.not_finished = False
                self.solver.quit()
                self.solver.done_signal.disconnect()

            elif self.algorithm_name == "tabu":
                if self.algorithm.iteration_finish:
                    self.algorithm.iteration_finish = False
                else:
                    self.solver.not_finished = False
                    self.solver.quit()
                    self.solver.done_signal.disconnect()

            self.next_iteration()
        except:
            self.next_iteration()

    def calculate_error(self):
        total_error = 0
        if self.function_type == "normal":
            for truck in self.solver.truck_list.values():
                if truck.truck_name in self.data.going_truck_name_list:
                    if truck.behaviour_list[truck.current_state] == "done":

                        if truck.finish_time > truck.upper_bound:
                            error = truck.finish_time - truck.upper_bound

                            print("positive error")
                        elif truck.finish_time < truck.lower_bound:
                            error = truck.finish_time - truck.lower_bound
                            # print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!negative error')
                            # print(error)
                        else:
                            error = 0
                        if self.slow_solution:
                            self.current_result_data.times[truck.truck_name].append(["upper bound", truck.upper_bound])
                            self.current_result_data.times[truck.truck_name].append(["lower bound", truck.lower_bound])
                            self.current_result_data.times[truck.truck_name].append(["error", error])

                    total_error += abs(error)
        elif self.function_type == "cmax":
            print("cmax")
            total_error = self.solver.current_time
            for truck in self.solver.truck_list.values():
                if truck.truck_name in self.data.going_truck_name_list:
                    if truck.behaviour_list[truck.current_state] == "done":
                        self.current_result_data.times[truck.truck_name].append(["upper bound", truck.upper_bound])
                        self.current_result_data.times[truck.truck_name].append(["lower bound", truck.lower_bound])

        elif self.function_type == "late_truck":
            for truck in self.solver.truck_list.values():
                if truck.truck_name in self.data.going_truck_name_list:
                    if truck.behaviour_list[truck.current_state] == "done":
                        error = 0
                        if truck.finish_time > truck.upper_bound:
                            error = truck.finish_time - truck.upper_bound
                            total_error += 1
                            error = 1
                        self.current_result_data.times[truck.truck_name].append(["upper bound", truck.upper_bound])
                        self.current_result_data.times[truck.truck_name].append(["lower bound", truck.lower_bound])
                        self.current_result_data.times[truck.truck_name].append(["error", error])

        return total_error

    def stop(self):
        print("stop")
        try:
            self.solver.done_signal.disconnect()
        except:
            pass

    def solve_one_sequence(self):
        self.data_set_number = self.data_set_spin_box.value() - 1
        self.solution_name = "data_set{0}_simulation_{1}".format(self.data_set_number + 1, len(self.results) + 1)
        self.results[self.solution_name] = []
        self.result_names_combo_box.addItem(self.solution_name)

        self.data_set_number = self.data_set_spin_box.value() - 1
        self.setup_truck_names()
        self.solver = Solver(self.data_set_number, self.data)
        self.solver.time_signal.connect(self.time.display)
        self.solver.value_signal.connect(self.solver_truck_signal)
        self.solver.value_signal.connect(self.time_saver)
        self.time_constant.textChanged.connect(self.solver.time_step_change)
        self.solver.done_signal.connect(self.finished)
        self.solver.time_step = True
        self.sequence = Sequence()
        for box in self.combobox_coming_sequence:
            self.sequence.coming_sequence.append(box.currentText())
        for box in self.combobox_going_sequence:
            self.sequence.going_sequence.append(box.currentText())
        self.graphicsView.reset()
        self.graphicsView.update_scene()
        self.solver.set_sequence(self.sequence)
        self.solver.solve()

    def solver_truck_signal(self, time, name, state, arg):
        self.truck_states[name] = [state, arg]
        self.graphicsView.update_scene()

    def time_saver(self, time, name, state, arg):
        try:
            if self.slow_solution:
                if name in self.result_times.keys():
                    self.result_times[name].append([state, time])
                else:
                    self.result_times[name] = [[state, time]]
        except:
            pass

    def pause(self):
        try:
            self.solver.pause = True
        except:
            pass

    def resume(self):
        try:
            self.solver.pause = False
        except:
            pass

    def finished(self, time):
        self.current_result_data = ResultData(self.data)
        self.current_result_data.times = copy.deepcopy(self.result_times)
        self.sequence.error = self.calculate_error()
        self.current_result_data.sequence = copy.deepcopy(self.sequence)
        self.current_result_data.goods = self.solver.return_goods()
        self.results[self.solution_name].append(self.current_result_data)

        print("quit")
        self.solver.not_finished = False
        self.solver.quit()

    def setup_simulator(self):
        self.graphicsView.reset()
        self.graphicsView.truck_states = self.truck_states

    def show_results(self):
        try:
            iteration_number = int(self.result_iteration_number_line_edit.text()) - 1
            if iteration_number > len(self.showing_result):
                self.result_iteration_number_line_edit.setText(str(len(self.showing_result)))
                iteration_number = len(self.showing_result)

            result_sequence_model = ResultSequenceTableModel(self.showing_result[iteration_number], self.data)
            self.sequence_table.setModel(result_sequence_model)

            result_good_model = ResultGoodTableModel(self.showing_result[iteration_number], self.data)
            self.good_in_out_table.setModel(result_good_model)
            self.good_in_out_table.resizeColumnsToContents()
            self.good_in_out_table.resizeRowsToContents()

            inbound_time_model = ResultTimeTableModel(
                self.showing_result[iteration_number], self.data.number_of_inbound_trucks, "inbound"
            )
            self.inbound_time_table.setModel(inbound_time_model)

            outbound_time_model = ResultTimeTableModel(
                self.showing_result[iteration_number], self.data.number_of_outbound_trucks, "outbound"
            )
            self.outbound_time_table.setModel(outbound_time_model)

            compound_time_model = ResultTimeTableModel(
                self.showing_result[iteration_number], self.data.number_of_compound_trucks, "compound"
            )
            self.compound_time_table.setModel(compound_time_model)
        except:
            pass

    def change_result_name(self, name):
        self.solution_name = name
        self.showing_result = self.results[name]

    def print_results(self, results, iteration_number):
        pass

    def gams_output(self):
        file_name, _ = QFileDialog.getSaveFileName(self, "Save file", "/home")
        # try:
        gams_writer(file_name, self.data_set_spin_box.value() - 1, self.data)