LoginSignup
1
1

More than 3 years have passed since last update.

python を 使った シルバーストーン曲線 の 描画

Posted at

1. シルバーストーン曲線 ビジュアライズゼーション

マクシー・シルバーストーン曲線 を pythonで ビジュアライズゼーションするコードです.
JupyterNotebook で動作確認済みです.
なお,現在入っているパラメタは超適当に置いてるので,各自で変更して使ってください.

fix_cost_simulator
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
%matplotlib inline

# set investigation cost
PLANT_COST = 9_999_999_999 # set plant cost [!]
LINE_COST = 99_999_999     # set line cost [!]
TOOLING_COST = 69_999_999   # set tooling cost [!]

# set how much lines a plant will have [!]
PLANNED_NUM_OF_LINE = 8

# set each condition of the capacity. (pcs/yr = pcs/day * day/mo * mo/yr) 
LINE_DAILY_CAPA = 999 # set daily line production capacity [!]
TOOLING_DAILY_CAPA = 599 # set daily tooling production capacity [!]
DAYS_PER_MONTH = 22 # set working days [!]
MONTHS_PER_YEAR = 12 # how many months in a year
LINE_CAPA = LINE_DAILY_CAPA * DAYS_PER_MONTH * MONTHS_PER_YEAR # calc line capacity per year
TOOLING_CAPA = TOOLING_DAILY_CAPA * DAYS_PER_MONTH * MONTHS_PER_YEAR # calc tooling capacity per year

# set the condition for this simulation
START_QTY = 100_000 # starting point(production number) for this simulation
PLOT_WIDTH = 1_000 # plotting width
MARGIN_RATIO = 0.9 # set safety margin (consider a risk of sales) [!]
PLANT_DEP_YEAR = 9 # set plant depreciation year [!]
LINE_DEP_YEAR = 9 # set line depreciation year [!]
TOOLING_DEP_YEAR = 2.2 # set tooling depreciation year [!]
END_QTY = PLANNED_NUM_OF_LINE * LINE_CAPA # calc the end of this simulation

# initialize number of line/tooling
line_num = math.ceil(START_QTY / LINE_CAPA) # initialize number of line
tooling_num = math.ceil(START_QTY / TOOLING_CAPA) # initialize number of tooling

plant_dep_qty =  END_QTY * PLANT_DEP_YEAR * MARGIN_RATIO # calc plant depreciation quantity

# generate data for simulation
x_range = np.arange(START_QTY, END_QTY, PLOT_WIDTH)
Y = []
p_line_capa = line_num * LINE_CAPA # calc initial line production capacity
p_tooling_capa = tooling_num * TOOLING_CAPA # calc initial tooling production capacity
for x in x_range:
    if x > p_line_capa: # if production qty is over line capa, add a new line
        line_num += 1
        p_line_capa = line_num * LINE_CAPA
    if x > p_tooling_capa: # if production qty is over tooling capa, add a new tooling
        tooling_num += 1
        p_tooling_capa = tooling_num * TOOLING_CAPA

    plant_alloc = PLANT_COST / plant_dep_qty # calc allocated cost of plant building cost
    line_alloc = line_num * LINE_COST / x / LINE_DEP_YEAR # calc allocated cost of line cost
    tooling_alloc = tooling_num * TOOLING_COST / x / TOOLING_DEP_YEAR # calc allocated cost of tooling cost
    all_alloc = plant_alloc + line_alloc + tooling_alloc
    if line_num > PLANNED_NUM_OF_LINE: # if line_num is over planned num of line, cause error.
        print('Error: line_num is over PLANNED_NUM_OF_LINE.')
        break
    Y.append(all_alloc)

# show the precondition of this simulation
precondition_dict = {}
precondition_dict['plant_building_cost [工場建屋費用]'] = f'{PLANT_COST:,}'
precondition_dict['line_building_cost [ライン敷設費用]'] = f'{LINE_COST:,}'
precondition_dict['tooling_cost [金型費用]'] = f'{TOOLING_COST:,}'
precondition_dict['max_line_num_per_a_plant [1工場あたり最大ライン敷設計画数(pcs/day)]'] = PLANNED_NUM_OF_LINE
precondition_dict['max_production_daily_capa [1日あたりライン生産能力(pcs/day)]'] = LINE_DAILY_CAPA
precondition_dict['max_tooling_daily_capa [1日あたり金型生産能力]'] = TOOLING_DAILY_CAPA
precondition_dict['plant_depreciation_year [工場建屋の償却設定年数]'] = PLANT_DEP_YEAR
precondition_dict['line_depreciation_year [ラインの償却設定年数]'] = LINE_DEP_YEAR
precondition_dict['tooling_depreciation_year [金型の償却設定年数]'] = TOOLING_DEP_YEAR
precondition_dict['max_line_num [最大ライン敷設数]'] = line_num
precondition_dict['max_tooling_num [最大金型数]'] = tooling_num
precondition_dict['plant_production_capa [工場の生産能力(pcs/yr)]'] = f'{END_QTY:,}'
df = pd.DataFrame(precondition_dict.values(), index=precondition_dict.keys(), columns=['precondition [前提条件]'])
display(df)

# set your plan
yourX = 1_000_000 # set your sales plan [!]
yourY = 999_999_999
for x, y in zip(x_range, Y):
    if x > yourX:
        yourY = y
        break

# show simulation result
plt.rcParams["font.size"] = 15
fig, ax = plt.subplots(1, 1, facecolor='#F5FBFF', figsize=(15,10))
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.plot(x_range, Y, c='green')
ax.vlines(x=yourX, ymin=min(Y), ymax=max(Y), color='red')
ax.text(x=yourX*1.03, y=max(Y)*0.995, s=f'{yourY:,.2f} @ ( line_num:{np.ceil(yourX/LINE_CAPA):.0f}, tooling_num:{np.ceil(yourX/TOOLING_CAPA):.0f} )', color='red', fontsize=20)
fig.savefig('./data/img/FixedCostSim.png')
plt.show()

image.png

  • Maxcy et al.[1965]silver stone でググると,自動車製造企業の財務戦略 -トヨタを素材として-が引っ掛かった.興味深い.
  • 1965年っていうと,当然ながら,EXCELもない時代.マクシーさんは手書きでプロットしていったのでしょう.python でこれだけ楽に描画できるのは本当に有難い.

2. バナナの叩き売り ビジュアライゼーション

banana_sim
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

def make_and_plot_data(p1, p2, b):
    X = np.arange(p1, p2, 1)
    Y = []
    for x in X:
        Y.append(b)
    ax.plot(X,Y,c='green')

X0 = 0
X1 = 50  # [!]
X2 = 100 # [!]
X3 = 200 # [!]

C0 = 2000 # 購入量 X0 以上,X1 未満の売り値 [!]
C1 = 1000 # 購入量 X1 以上,X2 未満の売り値 [!]
C2 = 500 # 購入量 X2 以上,X3 未満の売り値 [!]

yourX = 120 # [!]
yourY = 500 # [!]

plt.rcParams["font.size"] = 15
fig = plt.figure(facecolor='#F5FBFF', figsize=(15,10))
ax = fig.subplots(1,1)
make_and_plot_data(X0, X1, C0)
make_and_plot_data(X1, X2, C1)
make_and_plot_data(X2, X3, C2)
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: f'{int(x):,}'))
ax.vlines(x=yourX, ymin=0, ymax=C0, color='red')
ax.text(x=yourX*1.03, y=yourY*1.1, s=f'{yourY} @ {yourX:,}', color='red', fontsize=20)
fig.savefig('./data/img/bananaCostSim.png')
plt.show()

image.png

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1