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()
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()
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()
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)
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()