/*
 * Test2D.java
 *
 * Created on 10. listopad 2000, 11:40
 */

package timetable.test;

import timetable.solver.*;
import timetable.data.*;
import timetable.util.*;
/**
 *
 * @author  Administrator
 * @version 
 */
public class Test2D extends Object {
    protected java.io.OutputStreamWriter osw = null;
    protected java.io.FileOutputStream fos = null;
    
    /** Creates new Test2D */
    public Test2D() {
    }
    
    public void openOutput(String filename) throws java.io.IOException {
       fos = new java.io.FileOutputStream(filename);
       osw = new java.io.OutputStreamWriter(fos);
    }
    
    public void closeOutput() throws java.io.IOException {
        osw.flush(); osw.close(); fos.close();
    }
    
    public void print(String s) throws java.io.IOException {
        osw.write(s);
        osw.flush();
    }

    public void println(String s) throws java.io.IOException {
        print(s+"\n");
    }
    
    public void test(String file) {
        try {
            try {
                Config k = null;
                System.out.println("Test2D ");
                System.out.println("File:"+file);
                if (file==null) k = new Config(); else {
                    k=new Config(file);
                    System.out.println("Using configuration file: "+file);
                };
                System.out.println("Config loaded.");
                openOutput(k.get("T2_OUTPUT"));
                System.out.println("Outut file: "+k.get("T2_OUTPUT"));
                String firstVar = k.get("T2_FIRST_VAR");
                String secondVar = k.get("T2_SECOND_VAR");
                int fVFrom = k.getInt("T2_FIRST_VAL_FROM");
                int fVTo   = k.getInt("T2_FIRST_VAL_TO");
                int fVStep = k.getInt("T2_FIRST_VAL_STEP");
                int sVFrom = k.getInt("T2_SECOND_VAL_FROM");
                int sVTo   = k.getInt("T2_SECOND_VAL_TO");
                int sVStep = k.getInt("T2_SECOND_VAL_STEP");
                System.out.println("Variable \""+firstVar+"\" is iterated from "+fVFrom+" to "+fVTo+" step "+fVStep+".");
                System.out.println("Variable \""+secondVar+"\" is iterated from "+sVFrom+" to "+sVTo+" step "+sVStep+".");
                System.out.println("--------------------------------------------------------------------------------");
                println(""+firstVar+","+secondVar+",MinIter,PrumIter,PrumAkt,"+
                        "MaxNaplAkt,PrumNaplAkt,MaxNapl%,PrumNapl%,Poc100%,"+
                        "Doba,PrumDoba,PrumIterNap,PrumDobaNap");
                for (int first=fVFrom;first<=fVTo;first+=fVStep) {
                  if (firstVar.equalsIgnoreCase("ZDROJE")) {
                      k.set("GEN_UCEBEN",first);
                      k.set("GEN_VYUCUJICICH",first);
                      k.set("GEN_TRID",first);
                      k.set("GEN_SKUPIN_UCEBEN",first);
                  } else k.set(firstVar,first);
                  Problem prob [] = new Problem [k.getInt("POCET_POKUSU")];
                  for (int i=0;i<k.getInt("POCET_POKUSU");i++) {
                      if (k.existKey("T2_LOAD_PROBLEM")) {
                          String fname = k.get("T2_LOAD_PROBLEM")+first+"_"+(i+1)+".shd";
                          if (new java.io.File(fname).exists()) {
                              System.out.println("Using schedule: "+fname);
                              prob[i]=Problem.load(fname);
                          } else { 
                              System.out.println("Generating schedule: "+fname);
                              SmartGenerator g = new SmartGenerator(k);
                              prob[i] = g.generujCele();
                              prob[i].save(fname);
                          }
                      } else {
                          SmartGenerator g = new SmartGenerator(k);
                          prob[i] = g.generujCele();
                      }
                  }
                  boolean solverSucceed = false;
                  for (int second=sVFrom;second<=sVTo;second+=sVStep) {
                      long prumPocIter = 0, prumPocIterNapl = 0, minPocIter=0;
                      long prumPocAkt = 0, minPocAkt=0;
                      long prumPocNaplAkt = 0, minPocNaplAkt=0;
                      long prumDobaPlanNap = 0,prumDobaPlan = 0, minDobaPlan =0;
                      long poc100 = 0;
                      for (int pokus=0;pokus<k.getInt("POCET_POKUSU");pokus++) {
                          System.out.println(""+(pokus+1)+". Pokus");
                          Problem p = ((k.existKey("T2_SAME_PROBLEMS") && k.getInt("T2_SAME_PROBLEMS")!=0)?prob[0]:prob[pokus]);
                          p.config.set(firstVar,first);
                          p.config.set(secondVar,second);
                          System.out.println("Variable \""+firstVar+"\" set to "+p.config.get(firstVar)+".");
                          System.out.println("Variable \""+secondVar+"\" set to "+p.config.get(secondVar)+".");
                          p.reset();
                          Solver s = new Solver(p.config,p);
                          s.setValueSelection(new timetable.solver.strategy.value.MinValueSelection(p.config,new timetable.solver.strategy.Tabu(p.config),
                                               new timetable.solver.strategy.price.SingleActivityEvaluation(p.config)));
                          s.setVariableSelection(new timetable.solver.strategy.variable.WorstFirstVariableSelection(p.config));
                          s.solve();
                          System.out.println("Podarilo se naplanovat "+s.maxScheduledActivities+" aktivit z "+p.activities.size()+".");
                          System.out.println("Pouzito "+s.nrIters+" iteraci.");
                          Activity a=null;
                          int max=0;
                          for (int i=0;i<p.activities.size();i++) 
                            if (p.activities.get(i).nrRemoves>max || a==null) {
                                max = p.activities.get(i).nrRemoves;
                                a = p.activities.get(i);
                            }
                          System.out.println("Nejvice vadi aktivita "+a.name+" , vyhozena byla "+a.nrRemoves+"x");
                          System.out.println("Doba planovani "+s.solveTime+" ms.");
                          System.out.println("Doba generovani "+s.generateTime+" ms.");
                          System.out.println("Doba vyberu promenne "+s.selectVariableTime+" ms.");
                          System.out.println("Doba vyberu hodnoty "+s.selectValueTime+" ms.");
//                          System.out.println("  z toho tabu "+p.tabu.dobaTabu+" ms.");
                          if (p.activities.size()==s.maxScheduledActivities) {
                              poc100++;prumPocIterNapl+=s.nrIters;prumDobaPlanNap+=s.solveTime;solverSucceed=true;
                          }
                          prumPocIter+=s.nrIters;prumPocAkt+=p.activities.size();prumPocNaplAkt+=s.maxScheduledActivities;prumDobaPlan+=s.solveTime;
                          if (pokus==0 || ((double)minPocNaplAkt/minPocAkt)<((double)s.maxScheduledActivities/p.activities.size()) || 
                             (((double)minPocNaplAkt/minPocAkt)<((double)s.maxScheduledActivities/p.activities.size()) && minPocIter>s.nrIters)) {
                              minPocIter=s.nrIters;minDobaPlan=s.solveTime;minPocNaplAkt=s.maxScheduledActivities;minPocAkt=p.activities.size();
                          }; 
                      };
                      int  pocPokusu=k.getInt("POCET_POKUSU");
                      println(first+","+second+","+minPocIter+","+((double)prumPocIter/pocPokusu)+","+((double)prumPocAkt/pocPokusu)+","+
                              minPocNaplAkt+","+((double)prumPocNaplAkt/pocPokusu)+","+((double)100*minPocNaplAkt/minPocAkt)+","+
                              ((double)100*prumPocNaplAkt/prumPocAkt)+","+((double)100*poc100/pocPokusu)+","+minDobaPlan+","+((double)prumDobaPlan/pocPokusu)
                              +(poc100>0?","+((double)prumPocIterNapl/poc100)+","+((double)prumDobaPlanNap/poc100):"")
                              );
                      System.out.println("--------------------------------------------------------------------------------");
                  }
//                  if (!solverSucceed) first=fVTo;
                }
            } finally {
                closeOutput();
            };
        } catch (Exception e) {
            System.err.println("Error: "+e.getMessage());
            e.printStackTrace(System.err);
        }
    }
    
    public static void main(String[] args) {
      Test2D t = new Test2D();
      if (args.length>0) {
          for (int i=0;i<args.length;i++)
              t.test(args[i]);
      } else t.test(null);
    }
    

}
