/* Author: Algirdas Noreika. e-mail: Contact@Algirdas.COM // Optimizer class for CLM Logistics Model. */ package lt.ktu.gmj.tasks; import lt.ktu.gmj.*; import lt.ktu.gmj.analysis.*; import lt.ktu.gmj.propertySheet.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; class CLModelDomain extends Domain { static final String []dimensions={ "SH1-Product-Amount-Margin (units)", "SH1-Product-Amount-Available (units)", "SH1-Product-Amount-Per-Order (units)", "SH1-Stock-Check-Period (hours)", "SH1-Lack (units)", "SH2-Product-Amount-Margin (units)", "SH2-Product-Amount-Available (units)", "SH2-Product-Amount-Per-Order (units)", "SH2-Stock-Check-Period (hours)", "SH2-Lack (units)", "SH3-Product-Amount-Margin (units)", "SH3-Product-Amount-Available (units)", "SH3-Product-Amount-Per-Order (units)", "SH3-Stock-Check-Period (hours)", "SH3-Lack (units)", "ST1-Product-Amount-Margin (units)", "ST1-Product-Amount-Available (units)", "ST1-Product-Amount-Per-Order (units)", "ST1-Lack (units)" }; public String[] dimensions () { return dimensions; } CLModelDomain () { //SH1-Product-Amount-Margin (units) min[0]= 5; max[0]= 40; defaultPoint.x[0]= 20; //SH1-Product-Amount-Available (units) min[1]= 20; max[1]= 70; defaultPoint.x[1]= 50; //SH1-Product-Amount-Per-Order (units) min[2]= 10; max[2]= 30; defaultPoint.x[2]= 20; //SH1-Stock-Check-Period (hours) min[3]= 1; max[3]= 5; defaultPoint.x[3]= 2; //SH1-Lack (units) min[4]= 0; max[4]= 10; defaultPoint.x[4]= 5; //SH2-Product-Amount-Margin (units) min[5]= 5; max[5]= 40; defaultPoint.x[5]= 20; //SH2-Product-Amount-Available (units) min[6]= 20; max[6]= 70; defaultPoint.x[6]= 40; //SH2-Product-Amount-Per-Order (units) min[7]= 10; max[7]= 30; defaultPoint.x[7]= 20; //SH2-Stock-Check-Period (hours) min[8]= 1; max[8]= 5; defaultPoint.x[8]= 2; //SH2-Lack (units) min[9]= 0; max[9]= 14; defaultPoint.x[9]= 7; //SH3-Product-Amount-Margin (units) min[10]= 5; max[10]= 50; defaultPoint.x[10]= 30; //SH3-Product-Amount-Available (units) min[11]= 20; max[11]= 80; defaultPoint.x[11]= 50; //SH3-Product-Amount-Per-Order (units) min[12]= 10; max[12]= 30; defaultPoint.x[12]= 20; //SH3-Stock-Check-Period (hours) min[13]= 1; max[13]= 5; defaultPoint.x[13]= 2; //SH3-Lack (units) min[14]= 0; max[14]= 14; defaultPoint.x[14]= 7; //ST1-Product-Amount-Margin (units) min[15]= 10; max[15]= 50; defaultPoint.x[15]= 30; //ST1-Product-Amount-Available (units) min[16]= 30; max[16]= 90; defaultPoint.x[16]= 50; //ST1-Product-Amount-Per-Order (units) min[17]= 20; max[17]= 50; defaultPoint.x[17]= 35; //ST1-Lack (units) min[18]= 0; max[18]= 20; defaultPoint.x[18]= 10; } }; public class CLModel extends AbstractTask implements TaskWithAnalyzers { private CLMOptimizer cLMOpt = new CLMOptimizer();; private CLModelDomain domain=new CLModelDomain(); public Domain domain () { return domain; } public void customize (PropertyManager manager) {} public double f (lt.ktu.gmj.Point pt) { return cLMOpt.mIn(pt.x, domain.min, domain.max); } public Class[] analyzers () throws ClassNotFoundException { Class CLMClass = Class.forName( "lt.ktu.gmj.analysis.CLMA" ); return new Class[]{ CLMClass }; } }; //// /* Author: Algirdas Noreika. // Optimizer class for CLM Logistics Model. */ class CLMOptimizer { CTimeLine cTimeLn; public CDataLogger cDataLog; int i; // METHODS public CLMOptimizer(){ // - Constructor. cDataLog = null; cTimeLn = new CTimeLine(this); } //public static void main(String sA[]) { /* Parameters: - Shops Count; - Stores Count; - iProductAmountMargin; - iProductAmountAvailable; - iProductLack; - iProductAmountPerOrder; - iStockCheckPeriod; - iDemandPerDay; - iTruckPassagePeriod; - iTruckPassagePeriod; - iOrderFulfillPeriod; - mSetStoreTruckCount; - iEndTime; */ /* CLMOptimizer co = new CLMOptimizer(); int iIteration; for (iIteration=0; iIteration<100; iIteration++) { System.out.println("Iteration: " + iIteration); co.mStart(); if (co.cDataLog != null) { CDataBlock cDB = co.cDataLog.mLoadData(1); // Loading Tick 10 data. System.out.println("Data of Tick 10: Shop0AmountInStock(" + cDB.cSHD[0].iProductsAmountInStock + ") Shop0Demand(" + cDB.cSHD[0].iDemand + ")"); } } */ //} // -------------------- OPTIMIZING ---------------------- // SOF Procedure for optimization. // NOTE: If there's any ProductLack during simulation - Target function automatically results 1 - the worst value. // There must be counted price to store products and price of products Lack (not sold products), cos in some // cases there's a posibility, that a price to store a product is larger than not to sold some of them to the // customers. public double mIn(double pParams[], double dMin[], double dMax[]) { // Input parameters. double fX = 0; int iIndex, iShopIdx, iStoreIdx; int iShopLackCount = 0, iStoreLackCount = 0; CDataBlock cDB; // AIS:Amount In Stock, PAM:Product Amount Margin. double dfXShopAIS, dfXStoreAIS; // Storing in stock should be minimized. double dfXShopLack, dfXStoreLack; // Lack of products should be minimal. double dfXShopPAM, dfXStorePAM; // Stock ProductAmountMargin should be as low as possible in case does not heap a store with orders. double dfXShopPAPO, dfXStorePAPO; // ProductsAmountPerOrder should be as minimal as possible to keep low products level in stock. double dfXShopSCP; // The lower we have stock check period, the better we can keep an eye on our stock and to make more and smaller // orders. In other hand the better is longer stock check period - to does not heap a store with orders. // NOTE: There must be set a criteria about parameters importance, which of them are the most important. // Init PARAMS. mInit(); // Initializing defaults. int[] iShopProductAISMAX = new int[cDataLog.iShopCount]; int[] iShopAISTotal = new int[cDataLog.iShopCount]; int[] iShopLack = new int[cDataLog.iShopCount]; int[] iShopLackMAX = new int[cDataLog.iShopCount]; int[] iStoreProductAISMAX = new int[cDataLog.iStoreCount-1]; int[] iStoreAISTotal = new int[cDataLog.iStoreCount-1]; int[] iStoreLackMAX = new int[cDataLog.iStoreCount-1]; int[] iStoreLack = new int[cDataLog.iStoreCount-1]; cTimeLn.cMMan.cShop[0].iProductAmountMargin = (int) Math.round(pParams[0]); cTimeLn.cMMan.cShop[0].iProductAmountAvailable = (int) Math.round(pParams[1]); cTimeLn.cMMan.cShop[0].iProductAmountPerOrder = (int) Math.round(pParams[2]); cTimeLn.cMMan.cShop[0].iStockCheckPeriod = (int) Math.round(pParams[3]); cTimeLn.cMMan.cShop[1].iProductAmountMargin = (int) Math.round(pParams[5]); cTimeLn.cMMan.cShop[1].iProductAmountAvailable = (int) Math.round(pParams[6]); cTimeLn.cMMan.cShop[1].iProductAmountPerOrder = (int) Math.round(pParams[7]); cTimeLn.cMMan.cShop[1].iStockCheckPeriod = (int) Math.round(pParams[8]); cTimeLn.cMMan.cShop[2].iProductAmountMargin = (int) Math.round(pParams[10]); cTimeLn.cMMan.cShop[2].iProductAmountAvailable = (int) Math.round(pParams[11]); cTimeLn.cMMan.cShop[2].iProductAmountPerOrder = (int) Math.round(pParams[12]); cTimeLn.cMMan.cShop[2].iStockCheckPeriod = (int) Math.round(pParams[13]); cTimeLn.cMMan.cStore[0].iProductAmountMargin = (int) Math.round(pParams[15]); cTimeLn.cMMan.cStore[0].iProductAmountAvailable = (int) Math.round(pParams[16]); cTimeLn.cMMan.cStore[0].iProductAmountPerOrder = (int) Math.round(pParams[17]); mStartSimulation(); // Performing simulation. // Initialising. if (cDataLog != null) { cDB = cDataLog.mLoadData(0); // Shops. for (iShopIdx=0; iShopIdxdMax) dVal = dMax; return ( (dVal-dMin) / (dMax-dMin) ); } // EOF Procedures of optimization // -------------------- OPTIMIZING ---------------------- public void mStartSimulation(){ // - Starts logistics model simulation. cTimeLn.mStart(); } public void mStopSimulation(){ // - Stops logistics model simulation. } public void mPause(){ // - Pauses logistics model simulation. } public void mStart() { mInit(); // Initilising process. mStartSimulation(); } // - Vizualizes a completed Tick data. // Initialising time tick public void mTickInit() { // Starting loging Tick Data into Log. cDataLog.mNewTickDataBlock(); } // Time tick accomplished. public void mTickComplete() { // Information on shops. for (i=0; i iMax) iMax = daDatasetX[i][iSet]; } for (i=0; i 0 ) { // E_STORECHECKSTOCK Priority 1 bEventFound = false; for (i=0; i 0) { // Laisvu masinu yra. Galimas prekiu pervezimas. if (iTruckCountTotal >= 99999) {iTruckCountAvailable = 99999;} // Unlimited truck count. iTruckCountAvailable--; bTruckReady = true; } else { mPushTruckWaitQueue(cOrder); // Jei laisvu masinu nera - apdorotas uzsakymas statomas i eile. } //bOrderFulfilProgressOn = false; } // - Now truck available. If there are some orders waiting for truck we can proceed it. public void mTransportNextOrder() { if (iaWaitTruckQueue.size()>0) { cTransportOrd = (COrder) iaWaitTruckQueue.remove(0); } else { cTransportOrd = null; } } public void mProceedNextOrder() { // Proceeds next order in a queue. // Retrieving next. mGetFirstOrder(); if (cOrd != null) { //System.out.println("Retrieve ORDER inside: Client["+cOrd.iClientID+"]"); mFulfillOrder(cOrd.iClientID, cOrd.iClientType, cOrd.iAmount); } else { } } // - Fullfills Order or Places Order into an order queue. public void mFulfillOrder(int iClientID, int iClientType, int iAmount) { // - Uzsakymo gavimas ish uzsakovo (e'1...e'M+L). if ( !bOrderFulfilProgressOn ) { if (iProductAmountAvailable >= 99999) {iProductAmountAvailable = iProductAmountAvailable + iAmount;} // Unlimited Product Amount Avilable. iProductAmountAvailable = iProductAmountAvailable - iAmount; if (iProductAmountAvailable < 0 ) { iProductLack += (-iProductAmountAvailable); // Trukstamu prekiu kiekis padideja. //iProductAmountAvailable = 0; // Likutis prilyginamas 0. // (Store 3) If no more available products - order goes into orders queue. mPushOrder(iClientID, iClientType, (-iProductAmountAvailable)); iAmount+= iProductAmountAvailable; iProductAmountAvailable = 0; } if (iProductAmountAvailable + iAmount > 0) { // If no any other order fulfil and products available - fulfiling request. //System.out.println("FULFILING ORDER INSIDE: Client-" +iClientID + " iClientType-"+iClientType+ " iAmount-"+iAmount); bOrderFulfilProgressOn = true; bInitOrderFulfil = true; cCurrentOrd = new COrder(iClientID, iClientType, iAmount); } } else { // - (Store 1). mPushOrder(iClientID, iClientType, iAmount); } } // - Retrieves order from a order queue. public void mGetFirstOrder() { cOrd = null; if (iaOrdersQueue.size()>0) { //System.out.println("Retrieving order from Queue"); cOrd = (COrder) iaOrdersQueue.remove(0); //System.out.println("OrderClient:"+cOrd.iClientID); } else { cOrd = null; } } // Placing order into orders Queue. public void mPushOrder(int iClientID, int iClientType, int iAmount) { //System.out.println("Pushing Order into Queue: ID["+iClientID +"] Type["+iClientType+"] iAmount["+iAmount+"]"); cOrd = new COrder(iClientID, iClientType, iAmount); iaOrdersQueue.add(cOrd); } } // - Class describing a single order. class COrder { public int iClientID; public int iClientType; public int iAmount; public COrder(int iClntID, int iClntType, int iAmnt) { iClientID = iClntID; iClientType = iClntType; iAmount = iAmnt; } }; ////////////////// /*********************************************************** Title: CTimeLine - Time operations object class. Author: Algirdas Noreika; norealgi@soften.ktu.lt Date created: 2004-02-21 Description & Comments: - Performs Time management. ***********************************************************/ class CTimeLine { public int iTime; // - Time in hours (=0) on inicialization and reset. public int iEndTime; // - End time in hours. public CEventStack cEvtStack; public CModelManager cMMan; private int iTickerControl; // - (0)run;(1)Stop;(2)Pause; private CLMA cLM; private CLMOptimizer cLMOpt; //public FileOutputStream cFileOS; // METHODS CTimeLine(CLMA cLM){ // - Constructor. this.cLM = cLM; this.cLMOpt = null; cEvtStack = new CEventStack(); cMMan = new CModelManager(); } CTimeLine(CLMOptimizer cLMOpt){ // - Constructor. this.cLMOpt = cLMOpt; this.cLM = null; cEvtStack = new CEventStack(); cMMan = new CModelManager(); } public void mInitialize(){ // - Initilizes timeline. //try { iTime = 0; iTickerControl = 1; cEvtStack.mReset(); //System.out.println("Creating log file..."); //cFileOS = new FileOutputStream("clm.log", false); //cFileOS.write(new String("--- Logistics Model log file ---\n").getBytes()); //cDataLog = new CDataLogger(cMMan.cShop.length, cMMan.cStore.length); // Logging initial Shops and stores count. //cFileOS.write(new String("Shops Total: " + cMMan.cShop.length+"\n").getBytes()); //for (int iIndex=0; iIndex < cMMan.cShop.length; iIndex++) { // cFileOS.write(new String("Shop["+iIndex+"] Amount limit: " + cMMan.cShop[iIndex].iProductAmountMargin+"\n").getBytes()); // cFileOS.write(new String("Shop["+iIndex+"] Order amount: " + cMMan.cShop[iIndex].iProductAmountPerOrder+"\n").getBytes()); //} //cFileOS.write(new String("Stores Total: " + cMMan.cStore.length + ". Last Store - Supplier with unlimited product count.\n").getBytes()); //cFileOS.write(new String("Simulation period: " + iEndTime + " hours ("+ iEndTime/24 +" day's)\n").getBytes()); //} catch (FileNotFoundException e) { //} catch (IOException e) {} } public void mStart(){ // - Starts time counter. iTickerControl = 0; mTicker(); } public void mStop(){ // - Stops time counter. mInitialize(); } public void mPause(){ // - Pauses a time counter. iTickerControl = 2; } public void mTicker(){ // - A ticker loop. //System.out.println("Starting Simulation."); while(iTickerControl == 0 && iTime < iEndTime) { iTime++; mTickAction(); } //cFileOS.close(); //System.out.println("Simulation Complete."); } // - One single time tick action method. public void mTickAction() { // - Performs action available in event stack for current time tick. if (this.cLM != null) this.cLM.mTickInit(); if (this.cLMOpt != null) this.cLMOpt.mTickInit(); // - Performing sales; for (int iIndex=0; iIndex 0 && jTFStores.getText().length() >0) { // Setting Shops Count cTimeLn.cMMan.mSetShopCount(Integer.parseInt(jTFShops.getText())); // Setting Stores Count. cTimeLn.cMMan.mSetStoreCount(Integer.parseInt(jTFStores.getText())); cntPane.removeAll(); mInitDataContainers(); setSize(445,400); } } }); */ // -- End of Stores and Shops Count; // -- SOF Shop and Store parameters } private void mInitDataContainers() { cntPane = getContentPane(); cntPane.setLayout(new BorderLayout()); iSelIndex = 0; bShop = true; Container cntData = new Container(); // Stores Data // Creating selection. String[] sSelectionList = new String[cTimeLn.cMMan.cShop.length + cTimeLn.cMMan.cStore.length-1]; for (i=0; i