要求:
针对应力和强度服从正态、对数正态、指数、威布尔分布的任意组合,利用Monte-Carlo方法编制程序,进行可靠度仿真。
代码:
import random
import tkinter as tk
from turtle import position
class window:
def __init__(self):
self.root = tk.Tk()
self.root.title("Monte Carlo for Reliability")
self.root.geometry("800x600")
self.interface()
def interface(self):
"""
界面编写位置
"""
#应力
frame_s = tk.LabelFrame(self.root, text="Stress", labelanchor="n")
frame_s.place(relx=0.05, rely=0, relwidth=0.9, relheight=0.3)
#应力分布单选
frame_s_selection = tk.LabelFrame(frame_s, text="Stress distribution", labelanchor="n")
frame_s_selection.place(relx=0, rely=0, relwidth=0.2, relheight=0.9)
self.v_stress = tk.IntVar()
values = { "normal" : 1 , "exponential" : 2 , "weibull" : 3 , "lognormal" : 4}
for (text, value) in values.items():
tk.Radiobutton(frame_s_selection, text = text, variable = self.v_stress, value = value).grid(row = value, column = 0, sticky ='w')
#应力参数
tk.Label(frame_s,text="Please enter the parameters of the distribution in the text box:").place(relx=0.3, rely=0, relwidth=0.6, relheight=0.1)
#正态分布参数
tk.Label(frame_s,text="normal").place(relx=0.2, rely=0.1, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="μ:").place(relx=0.2, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="σ:").place(relx=0.2, rely=0.4, relwidth=0.1, relheight=0.1)
self.entrystress_mu = tk.DoubleVar()
self.stress_mu = tk.Entry(frame_s, textvariable=self.entrystress_mu).place(relx=0.3, rely=0.2, relwidth=0.1, relheight=0.1)
self.entrystress_sigma = tk.DoubleVar()
self.stress_sigma = tk.Entry(frame_s, textvariable=self.entrystress_sigma).place(relx=0.3, rely=0.4, relwidth=0.1, relheight=0.1)
#指数分布参数
tk.Label(frame_s,text="exponential").place(relx=0.4, rely=0.1, relwidth=0.15, relheight=0.1)
tk.Label(frame_s,text="λ:").place(relx=0.4, rely=0.3, relwidth=0.1, relheight=0.1)
self.entrystress_lambd = tk.DoubleVar()
self.stress_lambd = tk.Entry(frame_s, textvariable=self.entrystress_lambd).place(relx=0.5, rely=0.3, relwidth=0.1, relheight=0.1)
#威布尔分布参数
tk.Label(frame_s,text="weibull").place(relx=0.6, rely=0.1, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="m:").place(relx=0.6, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="θ-r:").place(relx=0.6, rely=0.4, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="r:").place(relx=0.6, rely=0.6, relwidth=0.1, relheight=0.1)
self.entrystress_m = tk.DoubleVar()
self.stress_m = tk.Entry(frame_s,textvariable=self.entrystress_m).place(relx=0.7, rely=0.2, relwidth=0.1, relheight=0.1)
self.entrystress_theta = tk.DoubleVar()
self.stress_theta = tk.Entry(frame_s,textvariable=self.entrystress_theta).place(relx=0.7, rely=0.4, relwidth=0.1, relheight=0.1)
self.entrystress_r = tk.DoubleVar()
self.stress_r = tk.Entry(frame_s,textvariable=self.entrystress_r).place(relx=0.7, rely=0.6, relwidth=0.1, relheight=0.1)
#对数正态分布参数
tk.Label(frame_s,text="lognormal").place(relx=0.8, rely=0.1, relwidth=0.15, relheight=0.1)
tk.Label(frame_s,text="μ:").place(relx=0.8, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_s,text="σ:").place(relx=0.8, rely=0.4, relwidth=0.1, relheight=0.1)
self.entrystress_logmu = tk.DoubleVar()
self.stress_logmu = tk.Entry(frame_s, textvariable=self.entrystress_logmu).place(relx=0.9, rely=0.2, relwidth=0.1, relheight=0.1)
self.entrystress_logsigma = tk.DoubleVar()
self.stress_logsigma = tk.Entry(frame_s, textvariable=self.entrystress_logsigma).place(relx=0.9, rely=0.4, relwidth=0.1, relheight=0.1)
#强度
frame_r = tk.LabelFrame(self.root, text="Resistance", labelanchor="n")
frame_r.place(relx=0.05, rely=0.3, relwidth=0.9, relheight=0.3)
#强度分布单选
frame_r_selection = tk.LabelFrame(frame_r, text="Resistance distribution", labelanchor="n")
frame_r_selection.place(relx=0, rely=0, relwidth=0.2, relheight=0.9)
self.v_resistance = tk.IntVar()
values = { "normal" : 1 , "exponential" : 2 , "weibull" : 3 , "lognormal" : 4}
for (text, value) in values.items():
tk.Radiobutton(frame_r_selection, text = text, variable = self.v_resistance, value = value).grid(row = value, column = 0, sticky ='w')
#强度参数
tk.Label(frame_r,text="Please enter the parameters of the distribution in the text box:").place(relx=0.3, rely=0, relwidth=0.6, relheight=0.1)
#正态分布参数
tk.Label(frame_r,text="normal").place(relx=0.2, rely=0.1, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="μ:").place(relx=0.2, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="σ:").place(relx=0.2, rely=0.4, relwidth=0.1, relheight=0.1)
self.entryresis_mu = tk.DoubleVar()
self.resistance_mu = tk.Entry(frame_r, textvariable=self.entryresis_mu).place(relx=0.3, rely=0.2, relwidth=0.1, relheight=0.1)
self.entryresis_sigma = tk.DoubleVar()
self.resistance_sigma = tk.Entry(frame_r, textvariable=self.entryresis_sigma).place(relx=0.3, rely=0.4, relwidth=0.1, relheight=0.1)
#指数分布参数
tk.Label(frame_r,text="exponential").place(relx=0.4, rely=0.1, relwidth=0.15, relheight=0.1)
tk.Label(frame_r,text="λ:").place(relx=0.4, rely=0.3, relwidth=0.1, relheight=0.1)
self.entryresis_lambd = tk.DoubleVar()
self.resistance_lambd = tk.Entry(frame_r, textvariable=self.entryresis_lambd).place(relx=0.5, rely=0.3, relwidth=0.1, relheight=0.1)
#威布尔分布参数
tk.Label(frame_r,text="weibull").place(relx=0.6, rely=0.1, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="m:").place(relx=0.6, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="θ-r:").place(relx=0.6, rely=0.4, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="r:").place(relx=0.6, rely=0.6, relwidth=0.1, relheight=0.1)
self.entryresis_m = tk.DoubleVar()
self.resistance_m = tk.Entry(frame_r, textvariable=self.entryresis_m).place(relx=0.7, rely=0.2, relwidth=0.1, relheight=0.1)
self.entryresis_theta = tk.DoubleVar()
self.resistance_theta = tk.Entry(frame_r, textvariable=self.entryresis_theta).place(relx=0.7, rely=0.4, relwidth=0.1, relheight=0.1)
self.entryresis_r = tk.DoubleVar()
self.resistance_r = tk.Entry(frame_r, textvariable=self.entryresis_r).place(relx=0.7, rely=0.6, relwidth=0.1, relheight=0.1)
#对数正态分布参数
tk.Label(frame_r,text="lognormal").place(relx=0.8, rely=0.1, relwidth=0.15, relheight=0.1)
tk.Label(frame_r,text="μ:").place(relx=0.8, rely=0.2, relwidth=0.1, relheight=0.1)
tk.Label(frame_r,text="σ:").place(relx=0.8, rely=0.4, relwidth=0.1, relheight=0.1)
self.entryresis_logmu = tk.DoubleVar()
self.resistance_logmu = tk.Entry(frame_r, textvariable=self.entryresis_logmu).place(relx=0.9, rely=0.2, relwidth=0.1, relheight=0.1)
self.entryresis_logsigma = tk.DoubleVar()
self.resistance_logsigma = tk.Entry(frame_r, textvariable=self.entryresis_logsigma).place(relx=0.9, rely=0.4, relwidth=0.1, relheight=0.1)
#模拟
self.frame = tk.LabelFrame(self.root, text="Simulation", labelanchor="n")
self.frame.place(relx=0.05, rely=0.6, relwidth=0.9, relheight=0.3)
tk.Label(self.frame,text="Please enter the number of simulations:").place(relx=0, rely=0.1, relwidth=0.4, relheight=0.1)
self.entrynum = tk.IntVar()
self.num = tk.Entry(self.frame, textvariable=self.entrynum).place(relx=0.4, rely=0.1, relwidth=0.2, relheight=0.1)
tk.Label(self.frame,text="Results:").place(relx=0.3, rely=0.3, relwidth=0.1, relheight=0.1)
self.Button0 = tk.Button(self.frame, text="Start", command=self.start, bg="#7bbfea")
self.Button0.place(relx=0.1, rely=0.5, relwidth=0.2, relheight=0.2)
def stress_random_data(self, num):
"""
Input:
num: represent the distribution type
1--normal; 2--exp; 3--weibull; 4--lognormal
"""
if num == 1:
mu = self.entrystress_mu.get()
sigma = self.entrystress_sigma.get()
data = random.normalvariate(mu, sigma)
elif num == 2:
lambd = self.entrystress_lambd.get()
data = random.expovariate(lambd)
elif num == 3:
scale = self.entrystress_m.get()
shape = self.entrystress_theta.get()
position = self.entrystress_r.get()
data = random.weibullvariate(scale, shape)+ position
else:
mu = self.entrystress_logmu.get()
sigma = self.entrystress_logsigma.get()
data = random.lognormvariate(mu,sigma)
return data
def resis_random_data(self, num):
"""
Input:
num: represent the distribution type
1--normal; 2--exp; 3--weibull; 4--lognormal
"""
if num == 1:
mu = self.entryresis_mu.get()
sigma = self.entryresis_sigma.get()
data = random.normalvariate(mu, sigma)
elif num == 2:
lambd = self.entryresis_lambd.get()
data = random.expovariate(lambd)
elif num == 3:
shape = self.entryresis_m.get()
scale = self.entryresis_theta.get()
position = self.entryresis_r.get()
data = random.weibullvariate(scale, shape) + position
else:
mu = self.entryresis_logmu.get()
sigma = self.entryresis_logsigma.get()
data = random.lognormvariate(mu,sigma)
return data
def start(self):
"""
开始运行Mente-Carlo模拟
"""
stress_dis = self.v_stress.get()
resistance_dis = self.v_resistance.get()
count = 0
for i in range(self.entrynum.get()):
s = self.stress_random_data(stress_dis)
r = self.resis_random_data(resistance_dis)
if r > s:
count +=1
R = count/self.entrynum.get()
self.results = tk.Label(self.frame, text = R).place(relx=0.4, rely=0.3, relwidth=0.2, relheight=0.1)
if __name__ == '__main__':
a = window()
a.root.mainloop()
界面结果
第一次做界面设计,还是很粗糙的,一些功能还有待改善。
并且一些变量名又臭又长……代码语句也不简洁,希望继续进步。