package com.ordobill.webapp.engine;
import java.util.ArrayList;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ordobill.webapp.beans.FigInform;
import com.ordobill.webapp.beans.Figures;
import com.ordobill.webapp.beans.Modeling;
import com.ordobill.webapp.beans.Project;
import com.ordobill.webapp.beans.SimulationFields;
import org.apache.commons.math3.distribution.NormalDistribution;
/**
* Simulation Engine에 필요한 것들을 구현하고 정의하는 클래스입니다.
* TypeOfFail와 TypeOfRepair 인터페이스를 상속 구현하였고, 실제 Engine에서 구현해야 하는
* SimulationBody 추상 메소드도 정의 되어있습니다.
*
* @author Choi Jin Wook(A.K.A Brian Choi @ Ordobill Office) / choijinwook84@gmail.com
* @version $ID: SimulationProp.java R365v
*
*/
public abstract class SimulationEngine implements TypeOfFailure, TypeOfRepair{
/**
* SimualtionProp의 생성자를 정의합니다.
* Project Bean 을 Parameter 로 받아 SimulationProp의 기본 변수들을
* 초기화 합니다.
* @param Project
*/
public SimulationEngine(Project project){
setSimTime(project.getProIterNum());
setStrTime(project.getProStartTime());
setLifeTime(project.getProLifeTime());
setTimeDiv(project.getProTd());
}
/**
* 기초 생성자입니다.
*/
public SimulationEngine(){}
/**
* Simulation Time
* */
private int simTime;
/**
* Starting time of Simulation(years)
*/
private int strTime;
/**
* Life Time(years)
*/
private int lifeTime;
/**
* Time Division(times)
*/
private float timeDiv;
/**
* Initialization from SimulationEngine
*/
private float present;
/**
* For Information figures when simulation each by
*/
private ArrayList<FigInform> figInformList = new ArrayList<FigInform>();
/**
* Accessor the simulation time
*
* @return The simulation time
*/
public int getSimTime() {
return simTime;
}
/**
* Mutator the simulation time
*
* @param simTime
*/
public void setSimTime(int simTime) {
this.simTime = simTime;
}
/**
* Accessor the start time
*
* @return The start time
*/
public int getStrTime() {
return strTime;
}
/**
* Mutator the start time
*
* @param strTime
*/
public void setStrTime(int strTime) {
this.strTime = strTime;
}
/**
* Accessor the life time
*
* @return The life time
*/
public int getLifeTime() {
return lifeTime;
}
/**
* Mutator the life time
*
* @param lifeTime
*/
public void setLifeTime(int lifeTime) {
this.lifeTime = lifeTime;
}
/**
* Accessor the time division
*
* @return The time division
*/
public float getTimeDiv() {
return timeDiv;
}
/**
* Mutator the time division
*
* @param timeDiv
*/
public void setTimeDiv(float timeDiv) {
this.timeDiv = timeDiv;
}
/**
* Accessor the present time
*
* @return The present time
*/
public float getPresent(){
return present;
}
/**
* Mutator the present time
*
* @param present
*/
public void setPresent(float present){
this.present = present;
}
/**
* Accessor the figures information list
*
* @return The figures information list
*/
public ArrayList<FigInform> getFigInformList() {
return figInformList;
}
/**
* Mutator the figures finformation list
*
* @param figInformList
*/
public void setFigInformList(ArrayList<FigInform> figInformList) {
this.figInformList = figInformList;
}
/**
* 실제로 시뮬레이션을 하는 메소드 입니다. SimulationProp에서 상속하여 구현해야 합니다.
* @deprecated for packing Figures per Equipment and probably doing Thread programing replaced by {@link #simulationBody(Vector)}
* @param figList
* @return SimulationFields[]를 반환합니다.
* @throws Exception
*/
@Deprecated public abstract SimulationFields[] simulationBody(ArrayList<Figures> figList) throws Exception;
/**
* 실제로 시뮬레이션을 하는 메소드 입니다. SimulationProp에서 상속하여 구현해야 합니다.
*
* @param modelingVector
* @return SimulationFields[]를 반환합니다.
* @throws Exception
*/
public abstract SimulationFields[] simulationBody(Vector<Modeling> modelingVector) throws Exception;
/**
* 속성값을 넣으면 해당하는Failure Type으로 HazardRate를 계산해서 반환합니다.
*
* @param Figures
* @return Hazard Rate
*/
public float selectFailType(Figures fig){
float harzardRate = 0f;
switch(fig.getFigDistribution()){
case 1 : harzardRate = exponentialFailType(fig.getFigFailureTime().floatValue(), fig.getFigBreakPoint().floatValue(), fig.getFigRecovFactor().floatValue(), fig.getFigRepModRelia(), fig.getFigRepRepeat(), fig.getFigRepUpto());
break;
case 2 : harzardRate = normalFailType(fig.getFigNormExptMttf().floatValue(), fig.getFigNormStdMttf().floatValue(),fig.getFigBreakPoint().floatValue(), 0f, "", "", 0);//TODO Normal
break;
case 3 : harzardRate = rectangularFailType(fig.getFigMinMttf().floatValue(),fig.getFigMaxMttf().floatValue(),fig.getFigBreakPoint().floatValue(),fig.getFigRecovFactor().floatValue(), fig.getFigRepModRelia(), fig.getFigRepRepeat(), fig.getFigRepUpto());//TODO Rectangular
break;
case 4 : harzardRate = triangularFailType(fig.getFigMinMttf().floatValue(),fig.getFigMaxMttf().floatValue(),fig.getFigMostMttf().floatValue(),fig.getFigBreakPoint().floatValue(), fig.getFigRecovFactor().floatValue(), fig.getFigRepModRelia(), fig.getFigRepRepeat(), fig.getFigRepUpto());//TODO Triangular
break;
case 5 : harzardRate = weibullTimeNoDelayType(fig.getFigWeiCharMttf().floatValue(), fig.getFigWeiShapeMttf().floatValue(), fig.getFigBreakPoint().floatValue(), fig.getFigRecovFactor().floatValue(), fig.getFigRepModRelia(), fig.getFigRepRepeat(), fig.getFigRepUpto());
break;
case 6 : harzardRate = weibullTimeDelayType(fig.getFigWeiCharMttf().floatValue(), fig.getFigWeiShapeMttf().floatValue(), fig.getFigBreakPoint().floatValue(), fig.getFigRecovFactor().floatValue(),0f, fig.getFigRepModRelia(), fig.getFigRepRepeat(), fig.getFigRepUpto());//TODO Weibull Time Delay
break;
default: harzardRate = 0f;//TODO
break;
}
//log.debug(harzardRate);
return harzardRate;
};
/**
* {@inheritDoc}
* @deprecated
*/
@Override
public float demandLoadFailType(float reliability, float failureTime) {
// TODO Auto-generated method stub
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public float exponentialFailType(float failureTime, float breakPoint, float reductionFactor, String repMod, String repRepeat, int repUpto) {
float exponentialHarzardRate = 0f;
exponentialHarzardRate = (1/failureTime)/timeDiv;
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
//Infinity is
}else if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
exponentialHarzardRate = exponentialHarzardRate / reductionFactor;
}
}
}
}
return exponentialHarzardRate;
}
/**
* {@inheritDoc}
*/
@Override
public float normalFailType(float expectedValue, float standardDeviation, float breakPoint, float reductionFactor, String repMod, String repRepeat, int repUpto) {
double normalHazardRate = 0d;
double presentLife = 0d;
if(breakPoint > 0f){
presentLife = getPresent() - breakPoint;
}else{
presentLife = getPresent();
}
//System.out.println(expectedValue);
//System.out.println(standardDeviation);
NormalDistribution normDist = new NormalDistribution(expectedValue, standardDeviation);
normalHazardRate = (normDist.density(presentLife)/(1-normDist.cumulativeProbability(presentLife)))/timeDiv;
//System.out.println(1-normDist.cumulativeProbability(presentLife));
//System.out.println(presentLife);
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
//Infinity is
}else if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
normalHazardRate = normalHazardRate / reductionFactor;
}
}
}
}
//System.out.println((double)normalHazardRate);
return (float)normalHazardRate;
}
/**
* {@inheritDoc}
*
*/
@Override
public float rectangularFailType(float minTtf, float maxTtf, float breakPoint, float reductionFactor, String repMod, String repRepeat, int repUpto) {
float rectangularHazardRate = 0f;
//Initialization of present with break time
minTtf += breakPoint;
maxTtf += breakPoint;
//Make Hazard Rate
if(minTtf <= getPresent() && maxTtf >= getPresent()){
rectangularHazardRate = (1/(maxTtf-getPresent()))/timeDiv;
}else if(maxTtf <= getPresent()){
rectangularHazardRate = 1f;
}
//Impact reduction factor
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
}
//Infinity is
if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
rectangularHazardRate = rectangularHazardRate / reductionFactor;
}
}
}
}
return rectangularHazardRate;
}
/**
* {@inheritDoc}
*/
@Override
public float triangularFailType(float minTtf, float maxTtf, float mostTtf, float breakPoint, float reductionFactor, String repMod, String repRepeat, int repUpto) {
double triangularHazardRate = 0d;
//Initialization of present with break time
minTtf += breakPoint;
maxTtf += breakPoint;
mostTtf += breakPoint;
//Make Hazard Rate
if(minTtf <= getPresent() && mostTtf >= getPresent()){
triangularHazardRate = (2*(getPresent()-minTtf))/((maxTtf-minTtf)*(mostTtf-minTtf)-Math.pow((getPresent()-minTtf), 2))/timeDiv;
}else if(mostTtf < getPresent() && maxTtf >= getPresent()){
triangularHazardRate = 2/(maxTtf-getPresent())/timeDiv;
}else if (maxTtf < getPresent()){
triangularHazardRate = 1d/timeDiv;
}
//Impact reduction factor
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
}
//Infinity is
if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
triangularHazardRate = triangularHazardRate / reductionFactor;
}
}
}
}
return (float)triangularHazardRate;
}
/**
* {@inheritDoc}
*/
@Override
public float weibullTimeNoDelayType(float characteristicLife, float shapeParameter, float breakPoint, float reductionFactor, String repMod, String repRepeat, int repUpto) {
// TODO Auto-generated method stub
float presentLife = 0f;
float maintenanceIntv = 0f;
//고장시점이 존재한다면
if(breakPoint > 0f){
//일정한 수리 시간이 있다면
if(maintenanceIntv > 0f){
if(((getPresent()%maintenanceIntv)<maintenanceIntv)&&(((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)<(getPresent()%maintenanceIntv))){
presentLife = ((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)-0f;
}else{
presentLife = getPresent()-breakPoint;
System.out.print("a");
}
//일정한 수리 식나이 없다면
}else{
if(breakPoint > getPresent()){
setPresent(breakPoint);
}
presentLife = getPresent()-breakPoint;
System.out.println(getPresent()+"-"+breakPoint);
System.out.print("b");
}
//고장시점이 존재하지 않는다면
}else{
//일정한 수리 시간이 있다면
if(maintenanceIntv > 0f){
if(((getPresent()%maintenanceIntv)<maintenanceIntv)&&(((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)<(getPresent()%maintenanceIntv))){
presentLife = ((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)-0f;
breakPoint = getPresent();
System.out.print("c");
}else{
presentLife = getPresent()-breakPoint;
System.out.print("d");
}
//일정한 수리시간이 없다면
}else{
presentLife = (getPresent())-0f;
System.out.print("f");
}
}
double hr = (shapeParameter/ (characteristicLife))*Math.pow((presentLife/ (characteristicLife)), shapeParameter -1f);
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
//Infinity is
}else if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
hr = hr / reductionFactor;
}
}
}
}
// System.out.println(presentLife);
return (float)hr/timeDiv;
}
/**
* {@inheritDoc}
*/
@Override
public float weibullTimeDelayType(float characteristicLife, float shapeParameter, float breakPoint, float reductionFactor , float timeDelay, String repMod, String repRepeat, int repUpto) {
double hr = 0;
float presentLife = 0f;
float maintenanceIntv = 0f;
//고장시점이 존재한다면
if(breakPoint > 0f){
//일정한 수리 시간이 있다면
if(maintenanceIntv > 0f){
if(((getPresent()%maintenanceIntv)<maintenanceIntv)&&(((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)<(getPresent()%maintenanceIntv))){
presentLife = ((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)-0f;
}else{
presentLife = getPresent()-breakPoint;
}
//일정한 수리 식나이 없다면
}else{
if(breakPoint > getPresent()){
setPresent(breakPoint);
}
presentLife = getPresent()-breakPoint;
}
//고장시점이 존재하지 않는다면
}else{
//일정한 수리 시간이 있다면
if(maintenanceIntv > 0f){
if(((getPresent()%maintenanceIntv)<maintenanceIntv)&&(((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)<(getPresent()%maintenanceIntv))){
presentLife = ((getPresent()+(1f/getTimeDiv()))%maintenanceIntv)-0f;
breakPoint = getPresent();
}else{
presentLife = getPresent()-breakPoint;
}
//일정한 수리시간이 없다면
}else{
presentLife = (getPresent())-0f;
}
}
timeDelay += breakPoint;
if(getPresent() > timeDelay){
hr = (shapeParameter/ (characteristicLife))*Math.pow((presentLife/ (characteristicLife)), shapeParameter -1f);
}
if(breakPoint>0f){
//Use the reduction Factor or Not
if("Y".equals(repMod)){
//Up to Number is
if("N".equals(repRepeat)){
//Infinity is
}else if("Y".equals(repRepeat)){
if(reductionFactor > 0f){
hr = hr / reductionFactor;
}
}
}
}
//System.out.println(breakPoint);
return (float)hr/timeDiv;
}
/**
* {@inheritDoc}
* @deprecated
*/
@Override
public float weibullAgeAtStartupType(float characteristicLife, float shapeFactor, float ageAtStartOfSim, String repMod, String repRepeat, int repUpto) {
// TODO Auto-generated method stub
return 0;
}
/**
* {@inheritDoc}
* @deprecated
*/
@Override
public float weibullTimeDelayOn1stFailType(float characteristicLife, float shapeFactor, float timeDelayToStart1stFailDist, String repMod, String repRepeat, int repUpto) {
// TODO Auto-generated method stub
return 0;
}
/**
* {@inheritDoc}
* @deprecated
*/
@Override
public float noneFailType() {
// TODO Auto-generated method stub
return 0;
}
//=======================RepairType Compose Start======================//
/**
* {@inheritDoc}
* @deprecated
*/
@Override
public float nonDeliveryRepairType() {
// TODO Auto-generated method stub
return 0;
}
//=======================Util for Simulation Start======================//
public void returnHazardRandom(String[] equipInform){
for(String eqInfo : equipInform){
String[] info = eqInfo.split(",");
FigInform figInform = new FigInform();
figInform.setFigUid(Integer.parseInt(info[0]));
figInform.setHazardRate(Float.parseFloat(info[1]));
figInform.setRandomNum(Float.parseFloat(info[2]));
figInformList.add(figInform);
figInform = null;
}
}
}