示例#1
0
 def test_write_and_read(self):
     proxy = SolverProxy()
     #par = Parameter(MODEL_2_QUAD, tau=.09, a=0.00146, s=.04, cr=.04, cn=.1, delta=.7956)
     par = Parameter(MODEL_1, tau=0.09, a=0.00146, s=.04, cn=.1)
     sol = proxy.read_or_calc_and_write(par, comment='unittest')
     proxy.commit()
     print(sol)
    def __calc__(self):
        p = Factorial
        iter = self.__state_iter
        proxy = SolverProxy()
        num = 0
        for tau, tau_state in iter(p.tau_lh()):
            for delta, delta_state in iter(p.delta_lh()):
                for cn, cn_state in iter(p.cn_lh()):
                    for cr, cr_state in iter(p.cr_lh(cn, delta)):
                        for s, s_state in iter(p.s_lh(cn)):
                            for a, a_state in iter(p.a_lh()):
                                # calculate model with restocking_fee
                                par_nb = Parameter(MODEL_NB, tau=tau, a=a, s=s, cn=cn)
                                sol_nb = proxy.read_or_calc_and_write(par_nb, resolution='middle')
                                num += 1; print(num)
                                #sol_nb = ModelNBSolver.solve(par_nb, 'low')
                                key_n = self.__key(MODEL_NB, tau_state, a_state, s_state, cr_state, cn_state, delta_state)
                                self._add(key_n, par_nb, sol_nb)

                                # calculate model two
                                par_o = Parameter(MODEL_2, tau=tau, a=a, s=s, cr=cr, cn=cn, delta=delta)
                                sol_o = proxy.calculate(par_o)
                                key_o = self.__key(MODEL_2, tau_state, a_state, s_state, cr_state, cn_state, delta_state)
                                self._add(key_o, par_o, sol_o)
        proxy.commit()
示例#3
0
    def __calc__(self):
        p = Factorial
        iter = self.__state_iter
        proxy = SolverProxy()
        num = 0
        for tau, tau_state in iter([p.tau_lo(), p.tau_hi()]):
            for cn, cn_state in iter([p.cn_lo(), p.cn_hi()]):
                for s, s_state in iter([p.s_lo(), p.s_hi(cn)]):
                    for a, a_state in iter([p.a_lo(), p.a_hi()]):
                        # calculate model with restocking_fee
                        par_nb = Parameter(MODEL_NB, tau=tau, a=a, s=s, cn=cn)
                        sol_nb = proxy.read_or_calc_and_write(
                            par_nb, resolution='high')
                        num += 1
                        print(num)
                        #sol_nb = ModelNBSolver.solve(par_nb, 'low')
                        key_nb = self.__key(MODEL_NB, tau_state, a_state,
                                            s_state, Factorial.HIGH, cn_state,
                                            Factorial.HIGH)
                        self._add(key_nb, par_nb, sol_nb)

                        # calculate model without online store
                        par_no = Parameter(MODEL_1, tau=tau, a=a, s=s, cn=cn)
                        sol_no = proxy.calculate(par_no)
                        key_no = self.__key(MODEL_1, tau_state, a_state,
                                            s_state, Factorial.HIGH, cn_state,
                                            Factorial.HIGH)
                        self._add(key_no, par_no, sol_no)
        proxy.commit()
示例#4
0
def test_db_and_plot():
    from matplotlib import pyplot as plt
    from solver import SolverProxy
    proxy = SolverProxy()
    a = [float(a) for a in np.linspace(0.0, 0.01, num=48 + 2)]
    x = np.zeros((len(a), 1))
    y = np.zeros((len(a), 1))
    for i, act_a in enumerate(a):
        if act_a == 0:
            x[0] = None
            y[0] = None
            continue
        par = Parameter(MODEL_2_QUAD, tau=0.09, a=act_a, s=0.04000000000000001, cn=0.1, cr=0.04000000000000001, delta=0.7956)
        #solP = ModelTwoQuadSolver.solve(par)
        solP = proxy.calculate(par, resolution='very-high')
        x[i] = solP.dec.wn
        y[i] = solP.profit_ret
        # plot actual a on x[i]
        #plt.text(act_a, x[i], str(act_a))
    proxy.commit()
    plt.plot(a, x, label='x', marker='o')
    plt.plot(a, y, label='y')
    plt.legend()
    #plt.savefig('figure_quad.pdf')
    plt.show()
示例#5
0
class Factorial:
    tau_lh = lambda: (.15, .5)
    s_lh = lambda cn: (0, cn / 2)
    cr_lh = lambda cn: (.1 * cn, .4 * cn)
    delta_lh = lambda: (.5, .85)
    cn_lh = lambda: (.1, .5)
    a_lh = lambda: (.001, .01)

    LOW, HIGH = 'LOW', 'HIGH'

    def __init__(self, model):
        self._model = model
        self._solverProxy = SolverProxy()
        self._calcTable()

    def _calcTable(self):
        self.__ff_table = [[None for j in range(8)] for i in range(8)]
        lohi = (0, 1)
        for i, (s, cr, a) in enumerate([(s, cr, a) for s in lohi for cr in lohi
                                        for a in lohi]):
            for j, (cn, delta, tau) in enumerate([(cn, delta, tau)
                                                  for cn in lohi
                                                  for delta in lohi
                                                  for tau in lohi]):
                tau_val = Factorial.tau_lh()[tau]
                delta_val = Factorial.delta_lh()[delta]
                cn_val = Factorial.cn_lh()[cn]
                cr_val = Factorial.cr_lh(cn_val)[cr]
                s_val = Factorial.s_lh(cn_val)[s]
                a_val = Factorial.a_lh()[a]

                par_o = Parameter(MODEL_2,
                                  tau=tau_val,
                                  a=a_val,
                                  s=s_val,
                                  cr=cr_val,
                                  cn=cn_val,
                                  delta=delta_val)
                par_n = Parameter(MODEL_1,
                                  tau=tau_val,
                                  a=a_val,
                                  s=s_val,
                                  cn=cn_val)
                par_nb = Parameter(MODEL_NB,
                                   tau=tau_val,
                                   a=a_val,
                                   s=s_val,
                                   cn=cn_val)
                par_oq = Parameter(MODEL_2_QUAD,
                                   tau=tau_val,
                                   a=a_val,
                                   s=s_val,
                                   cr=cr_val,
                                   cn=cn_val,
                                   delta=delta_val)
                par_nq = Parameter(MODEL_1_QUAD,
                                   tau=tau_val,
                                   a=a_val,
                                   s=s_val,
                                   cn=cn_val)

                if self._model == 'modelo':
                    par_1, par_2 = par_o, par_n
                elif self._model == 'modelnb':
                    par_1, par_2 = par_o, par_nb
                elif self._model == 'modeloq':
                    par_1, par_2 = par_oq, par_nq

                # solve
                self.__ff_table[i][j] = {
                    'par_1': par_1,
                    'par_2': par_2,
                    'sol_1': self._solverProxy.read_or_calc_and_write(par_1),
                    'sol_2': self._solverProxy.read_or_calc_and_write(par_2)
                }
                if self.__ff_table[i][j]['sol_2'] is None or self.__ff_table[
                        i][j]['sol_2'].profit_ret < 0.00005:
                    self.__ff_table[i][j]['sol_2'] = None
                print(par_2)
                self._solverProxy.commit()

    def _latex_percentage(self, value):
        if self._isLatex:
            return '{:.2f}\\%'.format(value * 100)
        else:
            return '{:.4f}'.format(value)

    def template_table_val(self, table, i, j):
        # sol_1 is online store!
        par_1, par_2 = self.__ff_table[i][j]['par_1'], self.__ff_table[i][j][
            'par_2']
        sol_1, sol_2 = self.__ff_table[i][j]['sol_1'], self.__ff_table[i][j][
            'sol_2']
        percentage = self._latex_percentage

        if table == 'case':
            case_1 = '-' if sol_1 is None else sol_1.case
            case_2 = '-' if sol_2 is None else sol_2.case
            return '{}/{}'.format(case_1, case_2)

        if None in (sol_1, sol_2): return '-'
        if table == 'profits':
            return percentage(sol_1.profit_man / sol_2.profit_man)
        elif table == 'retailerprof':
            return percentage(sol_1.profit_ret / sol_2.profit_ret)
        elif table == 'rho':
            return percentage(sol_1.dec.rho / sol_2.dec.rho)
        elif table == 'price_new':
            return percentage(sol_1.dec.pn / sol_2.dec.pn)
        elif table == 'wholesale_price':
            return percentage(sol_1.dec.wn / sol_2.dec.wn)
        elif table == 'restocking_price':
            return percentage(
                (sol_2.dec.b - par_2.s) / (sol_2.dec.wn - par_2.s))
        elif table == 'retailerprof2':
            return sol_2.profit_ret

    def getTemplateVariables(self):
        return {'esc': utils.escape_tex, 'ft': self.template_table_val}

    def render_template(self, tpl_filename, out_filename, isLatex):
        self._isLatex = isLatex
        env = Environment(loader=FileSystemLoader('templates'))
        template = env.get_template(tpl_filename)
        with open(out_filename, 'w', newline='\n') as f:
            renderedString = template.render(self.getTemplateVariables())
            f.write(renderedString)
示例#6
0
class CountourPlotter:
    def __init__(self, type, params):
        self.proxy = SolverProxy()
        self.type = type
        self.tau, self.s, self.cr, self.delta = params['tau'], params[
            's'], params['cr'], params['delta']
        self.count_a, self.lower_bound_a, self.upper_bound_a = params[
            'count_a'], params['lower_bound_a'], params['upper_bound_a']
        self.count_cn, self.lower_bound_cn, self.upper_bound_cn = params[
            'count_cn'], params['lower_bound_cn'], params['upper_bound_cn']
        self._calc_func = {
            PLOT_CASES_MODEL_TWO: self.__case_calc_func_model_two
        }[type]
        self.absolute = params['absolute']
        self.gray = params['gray']
        self.output = params['output']
        self.nolegend = params['nolegend']
        if type == PLOT_PROFIT_DIFFERENCE_MAN and self.absolute:
            self._calc_func = self.__profit_calc_func_man_absolute
        elif type == PLOT_PROFIT_DIFFERENCE_RET and self.absolute:
            self._calc_func = self.__profit_calc_func_ret_absolute
        elif type == PLOT_RHO_DIFFERENCE and self.absolute:
            self._calc_func = self.__rho_calc_func_absolute
        self.matrix = None

    def _a_cn_generator(self):
        """
            Helper generator to generate parameters for plotting
            it varies cn from [cr, 1] and a from [0, upper_bound_a]
            Returns a tuple of (par_model_1, par_model_2)
        """
        def __cr(cn):
            #if self.cr == 'delta*cn/2':
            #    return self.delta * cn / 2
            if self.cr == '0.5*cn':
                return 0.5 * cn
            else:
                return self.cr

        def __s(cn):
            if self.s == 'cn/2':
                return cn / 2
            else:
                return self.s

        for line, cn in enumerate(
                np.linspace(self.lower_bound_cn, self.upper_bound_cn,
                            self.count_cn)):
            for col, a in enumerate(
                    np.linspace(self.lower_bound_a, self.upper_bound_a,
                                self.count_a)):
                cn, a = float(cn), float(a)
                par_model_1 = None
                par_model_2 = Parameter(MODEL_2_QUAD,
                                        tau=self.tau,
                                        a=a,
                                        s=__s(cn),
                                        cr=__cr(cn),
                                        cn=cn,
                                        delta=self.delta)
                yield (line, col, par_model_1, par_model_2)

    def calc(self):
        self.nr_cols = self.count_a
        self.nr_lines = self.count_cn
        self.matrix = np.zeros([self.nr_lines, self.nr_cols])
        i = 0
        numall = self.nr_cols * self.nr_lines
        print(numall)
        #self.proxy.beginWrite()
        for line, col, par_model_1, par_model_2 in self._a_cn_generator():
            # calc solutions
            if par_model_2.a == .0:
                sol_model_1, sol_model_2 = None, None
            else:
                #sol_model_1 = solver_m1.optimize(par_model_1)
                #sol_model_2 = solver_m2.optimize(par_model_2)
                #sol_model_1 = self.proxy.read_or_calc_and_write(par_model_1, resolution='low')
                sol_model_1 = None  #todo hier fuer model 1 aufschalten
                #sol_model_2 = self.proxy.read_or_calc_and_write(par_model_2, resolution='low')
                sol_model_2 = self.proxy.calculate(par_model_2,
                                                   resolution=RESOLUTION)
            self.matrix[line, col] = self._calc_func(sol_model_1, sol_model_2,
                                                     par_model_2)
            if i % 100 == 0:
                #self.proxy.commit()
                print('{} ({:.2f} %)    at {}'.format(
                    i, (i / numall) * 100, str(datetime.datetime.now())))
            i += 1
        self.proxy.commit()
        #self.proxy.endWrite()

    def __profit_calc_func_man(self, sol_model_1, sol_model_2, par):
        if sol_model_1 is None or sol_model_2 is None:
            return np.nan
        rel = (sol_model_2.profit_man -
               sol_model_1.profit_man) / sol_model_1.profit_man
        #if rel <= 0 or rel >= .3:
        #if rel < .3:
        #    return np.nan
        #return max(0, min(.5, rel))
        return rel

    def __profit_calc_func_ret(self, sol_model_1, sol_model_2, par):
        if sol_model_1 is None or sol_model_2 is None:
            return np.nan
        rel = (sol_model_2.profit_ret -
               sol_model_1.profit_ret) / sol_model_1.profit_ret
        return rel

    def __profit_calc_func_ret_absolute(self, sol_model_1, sol_model_2, par):
        if sol_model_1 is None or sol_model_2 is None:
            return np.nan
        rel = sol_model_2.profit_ret - sol_model_1.profit_ret
        return rel

    def __profit_calc_func_man_absolute(self, sol_model_1, sol_model_2, par):
        if sol_model_1 is None and sol_model_2 is None or par.cn <= par.cr:
            return np.nan
        prof_1 = sol_model_1.profit_man if sol_model_1 is not None else 0
        prof_2 = sol_model_2.profit_man if sol_model_2 is not None else 0

        rel = (prof_2 - prof_1)
        return rel

    def __case_calc_func_model_one(self, sol_model_1, sol_model_2, par):
        return NotImplementedError()

    def __case_calc_func_model_two(self, sol_model_1, sol_model_2, par):
        if sol_model_2 == None:
            return np.nan
        #elif round(sol_model_2.profit_man, 1) == 0 or round(sol_model_2.profit_ret, 1) == 0:
        #    return np.nan
        else:
            return _ALL_CASES_MODEL_2.index(sol_model_2.case) + 1

    def plot_contourf(self):
        cmap = cm.gray if self.gray else None

        fig = plt.figure()
        ax = plt.subplot(111)

        levels, colors, extend = None, None, 'both'
        yticklabels = None

        if self.type == PLOT_PROFIT_DIFFERENCE_MAN:
            title = 'Increase of Profits with vs. without Online Store'
            side_title = r'relative increase of $\pi_{man}$'
            if self.absolute:
                side_title = side_title.replace('relative', 'absolute')
            cbar_ticks = None
        elif self.type == PLOT_PROFIT_DIFFERENCE_RET:
            title = 'Increase of Profits with vs. without Online Store'
            side_title = r'relative increase of $\pi_{ret}$'
            if self.absolute:
                side_title = side_title.replace('relative', 'absolute')
            cbar_ticks = None
        elif self.type == PLOT_RHO_DIFFERENCE:
            title = r'Increase of Efforts $\rho$ with vs. without Online Store'
            side_title = r'relative increase of $\rho$'
            if self.absolute:
                side_title = side_title.replace('relative', 'absolute')
            cbar_ticks = None
        elif self.type == PLOT_CASES_MODEL_ONE:
            title = r'Which case will be active in the event of no Online Shop'
            side_title = r'0 = no solution, 1 = case 1,   2 = case 2'
            levels = [0, 1, 2]
            yticklabels = r'case $\rho\geq1$', r'case $\rho = 1$'
        elif self.type == PLOT_CASES_MODEL_TWO:
            title = r'Which case will be active in the event of having an Online Shop'
            #side_title = r'1=c1a, 2=c1b, 3=c1c, 4=c2a, 5=c2b, 6=c3b'
            side_title = ''
            levels = [0, 1, 2, 3, 4, 5, 6]
            colors = [
                '#ee4b4b', '#e12726', '#960000', '#44db6b', '#0ed040',
                '#009727'
            ]
            yticklabels = '1a', '1b', '1c', '2a', '2b', '2c'
        elif self.type == PLOT_COMPARE_CASES:
            title = r'Comparison of Cases Model 1 vs. 2'
            cbar_ticks = None
            side_title = ''
            yticklabels = [
                'same case', 'M1C1, M2C2', 'M1C2, M2C1', 'S1N2', 'S2N1'
            ]
            levels = [0, 1, 2, 3, 4]
        #fig.suptitle(title)
        x_vector = np.linspace(self.lower_bound_a,
                               self.upper_bound_a,
                               num=self.nr_cols)  # x is a
        y_vector = np.linspace(self.lower_bound_cn,
                               self.upper_bound_cn,
                               num=self.nr_lines)  # y is cn

        cont = ax.contourf(x_vector,
                           y_vector,
                           self.matrix,
                           label='heatmap',
                           levels=levels,
                           colors=colors,
                           origin='lower',
                           extend=extend)
        cont.cmap.set_under('yellow')
        cont.cmap.set_over('cyan')
        cbar = fig.colorbar(cont)
        if yticklabels:
            cbar.ax.set_yticklabels(
                yticklabels)  # vertically oriented colorbar
        cbar.ax.set_ylabel(side_title)
        ax.set_xlabel('a')
        ax.set_ylabel(r'$c_n$')

        # Put a text of paramaters below current axis
        if not self.nolegend:
            txt = self.__par_txt()
            fig.text(0.20, 0.83, txt,
                     fontsize=12)  #, bbox=dict(facecolor='white', alpha=0.5))
            plt.subplots_adjust(bottom=0.15)
        if self.output == None: plt.show()
        else:
            plt.savefig(self.output)
        plt.close(fig)

    def __par_txt(self):
        if self.cr == 'delta*cn/2':
            _cr = r'$\frac{\delta*cn}{2}$'
        elif self.cr == '0.4*cn':
            _cr = '40% of cn'
        else:
            _cr = '{:.2f}'.format(self.cr)
        if self.s == 'cn/2':
            _s = r'$\frac{1}{2}cn$'
        else:
            _s = '{:.2f}'.format(self.s)
        return r'par: $\tau$={:.2f}, s={}, cr={}, $\delta$={:.2f}'.format(
            self.tau, _s, _cr, self.delta)

    def plot(self):
        self.plot_contourf()