Esempio n. 1
0
def cost_forecasting_evm():
    # Col 0 = ID, col 12 = Duration
    beta = beta_static_lookup[data_file]
    ACs = [0]  # init AT0 = 0
    EVs = [0]
    EAC_costs = []  # predict project duration
    start_test = False
    t = 1
    for period in tracking_periods:
        print("Tracking periods:", period)
        cols = find_column_indices(
            dfs[period].values[1],
            ["ID", "Actual Cost", "Earned Value (EV)", "Planned Value (PV)"])
        data_period = dfs[period].values[2:, cols]
        assert (baselines[:, 0] == data_period[:, 0]
                ).sum() == len(baselines), "Wrong permutation!"

        AC = data_period[0, 1]
        ACs.append(AC)
        EV = data_period[0, 2]
        PV = data_period[0, 3]
        if t >= (len(tracking_periods) * 2 / 3):
            # if True:
            CPI = EV / AC
            EAC = (BAC - EV) / CPI + AC
            print("Predict EAC:", EAC)
            EAC_costs.append(EAC)
        t += 1
    print("Project actual costs: ", data_period[0, 1])
    mape, error = MAPE([ACs[-1]] * len(EAC_costs[:-1]), EAC_costs[:-1])
    print("EVM MAPE: ", mape)
    return error, mape
Esempio n. 2
0
def cost_forecasting():
    # init trend
    Ts_AC = [BAC / n_tracking_periods]
    Ts_EV = [BAC / n_tracking_periods]
    print("T0_AC = T0_EV: ", Ts_AC[0])

    # Col 0 = ID, col 12 = Duration
    beta = beta_static_lookup[data_file]
    ACs = [0]  # init AT0 = 0
    t = 1
    EVs = [0]
    EAC_costs = []  # predict project duration
    start_test = False
    for period in tracking_periods:
        print("Tracking periods:", period)
        cols = find_column_indices(
            dfs[period].values[1],
            ["ID", "Actual Cost", "Earned Value (EV)", "Planned Value (PV)"])
        data_period = dfs[period].values[2:, cols]
        assert (baselines[:, 0] == data_period[:, 0]
                ).sum() == len(baselines), "Wrong permutation!"

        # current trend
        cur_AC = data_period[0, 1]
        ACs.append(cur_AC)
        T_AC = beta * (ACs[t] - ACs[t - 1]) + (1 - beta) * Ts_AC[t - 1]
        Ts_AC.append(T_AC)

        EV = data_period[0, 2]
        PV = data_period[0, 3]
        EVs.append(EV)
        T_EV = beta * (EVs[t] - EVs[t - 1]) + (1 - beta) * Ts_EV[t - 1]
        Ts_EV.append(T_EV)

        # if EV < PV and not start_test:
        #     start_test = True
        # if start_test:
        # if t >= (len(tracking_periods)*1/2) and T_EV > 0:
        # if T_EV > 0:
        # if t >= (len(tracking_periods)*2/3) and T_EV > 0:
        if T_EV > 0:
            k = (BAC - EVs[t]) / T_EV
            EAC = ACs[t] + k * T_AC
            EAC_costs.append(EAC)
            print("EAC:", EAC, k, T_AC)
        # end calculate
        t += 1
    print("Project actual costs: ", data_period[0, 1])
    mape, error = MAPE([ACs[-1]] * len(EAC_costs[:-1]), EAC_costs[:-1])
    print("MAPE: ", mape)
    # plt.plot(error)
    # plt.savefig(f"{data_file}-static.png")
    return error, mape
Esempio n. 3
0
def cost_forecasting():
    # init trend
    # Ts_AC = [BAC/n_tracking_periods]
    # Ts_EV = [BAC/n_tracking_periods]
    # print("T0_AC = T0_EV: ", Ts_AC[0])

    # Col 0 = ID, col 12 = Duration
    beta = 0.455  # người ta cho dữ liệu rồi, giờ cái mình cần làm là tìm ngược lại beta
    ACs = [0]  # init AC[0] = 0
    t = 1  # biến chạy trong vòng lặp tracking
    EVs = [0]  # khởi tạo mảng EV = [0]
    EAC_costs = []  # predict project duration
    start_test = False  # có làm cái gì với cái này đâu ????
    for period in tracking_periods:  # chỉ có một giai đoạn thôi
        print("Tracking periods:", period)
        cols = find_column_indices(dfs[period].values[1],
                                   ["ID", "PV", "EV", "AC"])
        print("cols ", cols)
        exit(0)
        data_period = dfs[period].values[2:, cols]
        assert (baselines[:, 0] == data_period[:, 0]
                ).sum() == len(baselines), "Wrong permutation!"

        # current trend
        cur_AC = data_period[0, 1]
        ACs.append(cur_AC)
        T_AC = beta * (ACs[t] - ACs[t - 1]) + (1 - beta) * Ts_AC[t - 1]
        Ts_AC.append(T_AC)

        EV = data_period[0, 2]
        PV = data_period[0, 3]
        EVs.append(EV)
        T_EV = beta * (EVs[t] - EVs[t - 1]) + (1 - beta) * Ts_EV[t - 1]
        Ts_EV.append(T_EV)

        # if EV < PV and not start_test:
        #     start_test = True
        # if start_test:
        # if t >= (len(tracking_periods)*1/2) and T_EV > 0:
        # if T_EV > 0:
        if t >= (len(tracking_periods) * 2 / 3) and T_EV > 0:
            # if T_EV > 0:
            k = (BAC - EVs[t]) / T_EV
            EAC = ACs[t] + k * T_AC
            EAC_costs.append(EAC)
            print("Predict EAC:", EAC)
        # end calculate
        t += 1
    # print("Project actual costs: ", data_period[0, 1])
    mape, error = MAPE([ACs[-1]] * len(EAC_costs[:-1]), EAC_costs[:-1])
    # print("MAPE: ", mape)
    return error, mape
Esempio n. 4
0
def dynamic_cost_without_recursive():
    # init trend
    Ts_AC = [BAC / n_tracking_periods]
    Ts_EV = [BAC / n_tracking_periods]
    init_T = BAC / n_tracking_periods
    print("T0_AC = T0_EV: ", Ts_AC[0])

    def select_best_beta(cur_AC):
        betas = []  # list of tuples (beta, MAPE)
        for beta in np.arange(0.0, 1, 0.05):  # e^beta*x
            _ACs = [0]
            _Ts_AC = [0]
            predict_ACs = []
            for prev_period in range(0, cur_period):
                # predict AC of current period, cur_AC = prev_AC + trend_AC
                data_prev_period = dfs[tracking_periods[prev_period]].values[
                    2:, cols]
                prev_AC = data_prev_period[0, 1]
                _ACs.append(prev_AC)
                _T_AC = beta * (_ACs[prev_period] - _ACs[prev_period - 1]) + (
                    1 - beta) * _Ts_AC[prev_period - 1]
                # _T_AC = calculate_current_trend(_ACs, beta, init_T)
                # _Ts_AC.append(_T_AC)
                # predict_AC = _ACs[prev_period-1] + (cur_period - prev_period)*_Ts_AC[prev_period-1]
                predict_AC = _ACs[prev_period -
                                  1] + (cur_period - prev_period) * _T_AC
                predict_ACs.append(predict_AC)
            if len(predict_ACs) == 0:
                error = 0
            else:
                ytrue = np.array([cur_AC] * len(predict_ACs))
                ypred = np.array(predict_ACs)
                error = np.abs((ytrue - ypred) / ytrue) * 100
                # weights = np.abs(0.5 - np.arange(0, 1, 1/len(error)))
                weights = 1 - np.arange(0, 1, 1 / len(error))[:len(error)]
                # weights = 1/(1+np.exp(-np.arange(0,1,1/len(error)))) - 0.5
                # weights = np.ones(len(error))
                # error = np.sum(error*weights) / weights.sum()
                error = np.sum(error * weights)
            # error = np.mean(error)

            # error = MAPE([cur_AC]*len(predict_ACs), [predict_AC])
            # prev_period = cur_period - 1
            # # _T_AC = beta*(_ACs[prev_period] - _ACs[prev_period-1]) + (1-beta) * _Ts_AC[prev_period-1]
            # _T_AC = calculate_current_trend(_ACs, beta)
            # predict_AC = _ACs[-1] + _T_AC
            # error = MAPE([cur_AC], [predict_AC])
            betas.append((beta, error))
        # select best beta
        beta = sorted(betas, key=lambda x: x[1])[0][0]
        return beta

    def calculate_current_trend(ACs, beta, init_T):
        # ACs[0] must be equals to 0
        if len(ACs) == 1: return init_T
        prev_T = calculate_current_trend(ACs[:-1], beta, init_T)
        T = beta * (ACs[-1] - ACs[-2]) + (1 - beta) * prev_T
        return T

    # Col 0 = ID, col 12 = Duration
    ACs = [0]  # init AT0 = 0
    t = 1
    EVs = [0]
    EAC_costs = []  # predict project duration
    start_test = False
    cols = find_column_indices(
        dfs[tracking_periods[0]].values[1],
        ["ID", "Actual Cost", "Earned Value (EV)", "Planned Value (PV)"])
    betas = []
    for cur_period, period in enumerate(tracking_periods):
        print("=== Tracking periods:", period)
        data_period = dfs[period].values[2:, cols]
        cur_AC = data_period[0, 1]
        ACs.append(cur_AC)
        # find optimal beta
        beta = select_best_beta(cur_AC)
        print("Best beta", beta)
        # current trend
        # T_AC = beta*(ACs[t] - ACs[t-1]) + (1-beta)*Ts_AC[t-1]
        T_AC = calculate_current_trend(ACs, beta, init_T)
        Ts_AC.append(T_AC)

        EV = data_period[0, 2]
        PV = data_period[0, 3]
        EVs.append(EV)
        T_EV = beta * (EVs[t] - EVs[t - 1]) + (1 - beta) * Ts_EV[t - 1]
        Ts_EV.append(T_EV)

        if EV < PV and not start_test:
            start_test = True
        if start_test:
            betas.append(beta)
            k = (BAC - EVs[t]) / T_EV
            EAC = ACs[t] + k * T_AC
            EAC_costs.append(EAC)
            print(f"EAC: {EAC:.3f}\t{k}\t{T_AC}")
        # end calculate
        t += 1
    print("Project actual costs: ", ACs[-1])
    mape, error = MAPE([ACs[-1]] * len(EAC_costs[:-1]), EAC_costs[:-1])
    print(f"Dynamic MAPE: {mape:.2f}")
    # plt.figure()
    # plt.plot(betas)
    # plt.xlabel("tracking periods")
    # plt.xticks(np.arange(len(betas)))
    # plt.ylabel("beta")
    # plt.savefig(f"figures/{data_file}-beta.png")
    return error, mape, ACs[-len(error):], EAC_costs[:-1], betas[:-1]
Esempio n. 5
0
def dynamic_cost():
    # planned duration
    BAC = baselines[0,2]
    # tracking periods
    tracking_periods = [x for x in sheetnames if "TP" in x]
    n_tracking_periods = len(tracking_periods)
    print("BAC:", BAC)
    print("Number of tracking periods:", n_tracking_periods)
    # init trend
    Ts_AC = [BAC/n_tracking_periods]
    Ts_EV = [BAC/n_tracking_periods]
    init_T = BAC/n_tracking_periods
    print("T0_AC = T0_EV: ", Ts_AC[0])

    def select_best_beta(cur_AC):
        betas = [] # list of tuples (beta, MAPE)
        for beta in np.arange(0.0, 1, 0.05):
            _ACs = [0]
            _Ts_AC = [0]
            predict_ACs = []
            for prev_period in range(0, cur_period):
                # predict AC of current period, cur_AC = prev_AC + trend_AC
                data_prev_period = dfs[tracking_periods[prev_period]].values[2:, cols]
                prev_AC = data_prev_period[0, 1]
                _ACs.append(prev_AC)
                _T_AC = beta*(_ACs[prev_period] - _ACs[prev_period-1]) + (1-beta) * _Ts_AC[prev_period-1]
                _Ts_AC.append(_T_AC)
                predict_AC = _ACs[prev_period-1] + (cur_period - prev_period)*_Ts_AC[prev_period-1]
                predict_ACs.append(predict_AC)
            error = MAPE([cur_AC]*len(predict_ACs), predict_ACs)
            betas.append((beta, error))
        # select best beta
        beta = sorted(betas, key=lambda x: x[1])[0][0]
        return beta

    def calculate_current_trend(ACs, beta):
        # ACs[0] must be equals to 0
        if len(ACs) == 1: return init_T
        prev_T = calculate_current_trend(ACs[:-1], beta)
        T = beta*(ACs[-1] - ACs[-2]) + (1-beta) * prev_T
        return T

    # Col 0 = ID, col 12 = Duration
    ACs = [0] # init AT0 = 0
    t = 1
    EVs = [0]
    EAC_costs = [] # predict project duration
    start_test = False
    cols = find_column_indices(dfs[tracking_periods[0]].values[1], ["ID", "Actual Cost", "Earned Value (EV)", "Planned Value (PV)"])
    for cur_period, period in enumerate(tracking_periods):
        print("=== Tracking periods:", period)
        data_period = dfs[period].values[2:, cols]
        cur_AC = data_period[0, 1]
        ACs.append(cur_AC)
        # find optimal beta
        beta = select_best_beta(cur_AC)
        print("Best beta", beta)
        # current trend
        # T_AC = beta*(ACs[t] - ACs[t-1]) + (1-beta)*Ts_AC[t-1]
        T_AC = calculate_current_trend(ACs, beta)
        Ts_AC.append(T_AC)

        EV = data_period[0,2]
        PV = data_period[0,3]
        EVs.append(EV)
        T_EV = beta*(EVs[t] - EVs[t-1]) + (1-beta)*Ts_EV[t-1]
        Ts_EV.append(T_EV)

        if EV < PV and not start_test:
            start_test = True
        if start_test:
            k = (BAC-EVs[t]) / T_EV
            EAC = ACs[t] + k * T_AC
            EAC_costs.append(EAC)
            print(f"EAC: {EAC:.3f}\t{k}\t{T_AC}")
        # end calculate
        t += 1
    print("Project actual costs: ", ACs[-1])
    mape, error = MAPE([ACs[-1]]*len(EAC_costs[:-1]), EAC_costs[:-1])
    print(f"Dynamic MAPE: {mape:.2f}")
    # plt.plot(error)
    # plt.savefig(f"{data_file}-dyn.png")
    return error
Esempio n. 6
0
def dynamic_cost():
    # init trend
    Ts_AC = [BAC / n_tracking_periods]
    Ts_EV = [BAC / n_tracking_periods]
    init_T = BAC / n_tracking_periods
    print("T0_AC = T0_EV: ", Ts_AC[0])

    def select_best_beta(cur_AC):
        betas = []  # list of tuples (beta, MAPE)
        for beta in np.arange(0.0, 1, 0.05):  # e^beta*x
            _ACs = [0]
            _Ts_AC = [0]
            predict_ACs = []
            for prev_period in range(0, cur_period):
                # predict AC of current period, cur_AC = prev_AC + trend_AC
                data_prev_period = dfs[tracking_periods[prev_period]].values[
                    2:, cols]
                prev_AC = data_prev_period[0, 1]
                _ACs.append(prev_AC)
                _T_AC = calculate_current_trend(_ACs, beta, init_T)
                predict_AC = _ACs[prev_period -
                                  1] + (cur_period - prev_period) * _T_AC
                predict_ACs.append(predict_AC)
            if len(predict_ACs) == 0:
                error = 0
            else:
                ytrue = np.array([cur_AC] * len(predict_ACs))
                ypred = np.array(predict_ACs)
                error = np.abs((ytrue - ypred) / ytrue) * 100
                weights = 1 - np.arange(0, 1, 1 / len(error))[:len(error)]
                # weights = np.zeros(len(error))
                # weights[-1] = 1
                error = np.sum(error * weights)
            betas.append((beta, error))
        # select best beta
        beta = sorted(betas, key=lambda x: x[1])[0][0]
        return beta

    def calculate_current_trend(ACs, beta, init_T):
        # ACs[0] must be equals to 0
        if len(ACs) == 1: return init_T
        prev_T = calculate_current_trend(ACs[:-1], beta, init_T)
        T = beta * (ACs[-1] - ACs[-2]) + (1 - beta) * prev_T
        return T

    # Col 0 = ID, col 12 = Duration
    ACs = [0]  # init AT0 = 0
    t = 1
    EVs = [0]
    EAC_costs = []  # predict project duration
    start_test = False
    cols = find_column_indices(
        dfs[tracking_periods[0]].values[1],
        ["ID", "Actual Cost", "Earned Value (EV)", "Planned Value (PV)"])
    betas = []
    for cur_period, period in enumerate(tracking_periods):
        print("=== Tracking periods:", period)
        data_period = dfs[period].values[2:, cols]
        cur_AC = data_period[0, 1]
        ACs.append(cur_AC)
        # find optimal beta
        beta = select_best_beta(cur_AC)
        print(f"Best beta {beta:.3f}", )
        # current trend
        # T_AC = beta*(ACs[t] - ACs[t-1]) + (1-beta)*Ts_AC[t-1]
        T_AC = calculate_current_trend(ACs, beta, init_T)
        Ts_AC.append(T_AC)

        EV = data_period[0, 2]
        PV = data_period[0, 3]
        EVs.append(EV)
        T_EV = beta * (EVs[t] - EVs[t - 1]) + (1 - beta) * Ts_EV[t - 1]
        Ts_EV.append(T_EV)

        # if EV < PV and not start_test:
        #     start_test = True
        # if start_test:
        if t >= (len(tracking_periods) * 2 / 3) and T_EV > 0:
            # if T_EV > 0:
            betas.append(beta)
            k = (BAC - EVs[t]) / T_EV
            EAC = ACs[t] + k * T_AC
            EAC_costs.append(EAC)
            print(f"Predict EAC: {EAC:.3f}")
        # end calculate
        t += 1
    print("Project actual costs: ", ACs[-1])
    mape, error = MAPE([ACs[-1]] * len(EAC_costs[:-1]), EAC_costs[:-1])
    print(f"Dynamic MAPE: {mape:.2f}")
    return error, mape, ACs[-len(error):], EAC_costs[:-1], betas[:-1]