Atgal

Failas: Tvarka.java


import lt.ktu.gmj.*;
import lt.ktu.gmj.propertySheet.*;

import java.io.*;
import java.util.Random;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.*;
import lt.monarch.awt.*;

//--------------------------------------------------------------------------

public class Tvarka implements Task
{ public static final String C_LANGAS = "X";
public static Tvarka gTvarka = null;

public static Tvarka getTvarka()
{ System.runFinalization();
return gTvarka;
}

public Tvarka ()
{ System.out.println("Tvarka() begin");
gTvarka = this;
}

protected void finalize() throws Throwable
{ System.out.println("Tvarka::finalize() begin");
gTvarka = null;
super.finalize();
}

public final int maxMokytoju = 64;
public final int maxPamoku = 7;
public final int maxDienu = 5;
public final int maxInfo = 3;

public int eMo=64; public int sMo=38;

public String [][] Mokytojai = new String[eMo][sMo];
public String [][] Mokytojai0 = new String[eMo][sMo];
private String klaidosTekstas = new String ("");

private int firsttime = 0;
public int K = 2;

public String data_url=new String( GlobalTools.getCodeBase()+"mokytojai.txt" );
public String write_program_url=new String( GlobalTools.getCodeBase()+"write.cgi" );

public void customize (PropertyManager manager)
{ manager.add ( new IntProperty ("K number of repetitions",
new TvarkaIntProvider (this),1,100));

manager.add ( new UrlProperty("URL of data file",
new TvarkaDataUrlProvider (this)));
}

private int kel;
private int kurKlaida = -1;
private double eval;
private double eval0;

public int number_of_variables=1;
private double norm_point[];
private double norm_eval[], n_eval[];
private Random rnd = new Random();
private TvarkaDomain domain=new TvarkaDomain();

public Domain domain ()
{ return domain; }

public double f (Point pt)
{ if (firsttime ==0){ try { NewInput(); }
catch (IOException e){ GlobalTools.showError(e);
return -1.0;
}
firsttime=1;
}
main ( pt );
return eval0;
}

private void NewInput() throws IOException
{ InputStreamReader file;
boolean bIsNewFileFormat;

file = GlobalTools.getInputStreamReader( data_url );
char[] buf = new char[3];
file.read(buf, 0, 3);
String str = new String(buf);
file.close();

if ( str.compareTo("Nr.")==0 ){ bIsNewFileFormat = true;
System.out.println("File open: Assuming NEW file format.");
}
else{ bIsNewFileFormat = false;
System.out.println("File open: Assuming OLD file format.");
}

boolean bIsCaption, bIsNumber;
if (bIsNewFileFormat){ bIsCaption = bIsNumber = true; }
else{ bIsCaption = bIsNumber = false; }

file = GlobalTools.getInputStreamReader( data_url);
BufferedReader r = new BufferedReader( file );
if (bIsCaption) r.readLine();
StreamTokenizer st = new StreamTokenizer( r );
st.resetSyntax();
st.whitespaceChars( '\u0000', '\u0020' );
st.wordChars( '\u0020'+1, '\u00FF' );

for ( int i=0; i<eMo; i++ ){ if (bIsNumber) st.nextToken(); for(int j=0; j<sMo; j++){ st.nextToken();
if (st.ttype == st.TT_WORD) Mokytojai[i][j] = st.sval;
}
}
r.close();
file.close();
System.out.println("Data ready...");
}

//------------------ Pagrindinis skaiciavimu metodas -----------------------
// Nuo sitos vietos prasideda pakeitimai :)

private void main ( Point pt )
{ // Suskaiciuojami pradiniai langai
eval0 = geriausias();
// Perrasomas pradinis tvarkarastis Mokytojai[i][j] i Mokytojai0[i][j]
synchronized ( Mokytojai0 ){ for ( int i = 0; i < eMo; i++ ) for (int j = 0; j < sMo; j++ ) Mokytojai0[i][j] = Mokytojai[i][j]; }
System.out.print ( "eval0 " );
System.out.println ( eval0 );

int it = 0;
// Parindinis ciklas, skaiciuojantis iteracijas
while ( it < K )
{ it++;
kel = 0;
// Ciklas einantis per mokytojus
while ( kel < eMo )
{ double x = rnd.nextDouble ();
if ( x > pt.x[0] ) if ( ieskoti ( kel ) ){ eval = geriausias();
if ( eval < eval0 ){ // Jei ivyko pakeitimas ir tvarkarastis geresnis negu buvo tai jis yra uzsaugomas
eval0 = eval;
System.out.print ( "eval0 " );
System.out.println ( eval0 );
synchronized ( Mokytojai0 ){ for ( int i = 0; i < eMo; i++ ) for (int j = 0; j < sMo; j++ ) Mokytojai0[i][j] = Mokytojai[i][j]; }
}
}
kel++;
}
}
}

//--------------------------------- Iesko atsitiktines patogios paskaitos ir lango -------------

// Grazina TRUE jei rasta ir sukeista arba FALSE kitu atveju
private boolean ieskoti ( int kel )
{ int langoVieta = 0;
int patogiPamoka = 0;
boolean isRyto = false;
double kurisX = rnd.nextDouble () * 20;
int iter = 0;
int j = 0;
while ( iter < kurisX ){ // Ieskom lango
if ( Mokytojai[kel][j].equals ( C_LANGAS ) ){ langoVieta = j;
iter++;
}
// Ieskom patogios paskatos
if ( Mokytojai[kel][j].equals ( "Q" ) && ( Mokytojai[kel][j+1].startsWith("P") ||
Mokytojai[kel][j+1].startsWith("A") ||
Mokytojai[kel][j+1].startsWith("T") ||
Mokytojai[kel][j+1].startsWith("K") ||
Mokytojai[kel][j+1].startsWith("N") ) ){
patogiPamoka = j + 1;
isRyto = true;
iter++;
}
if ( Mokytojai[kel][j+1].equals ( "Q" ) && ( Mokytojai[kel][j].startsWith("P") ||
Mokytojai[kel][j].startsWith("A") ||
Mokytojai[kel][j].startsWith("T") ||
Mokytojai[kel][j].startsWith("K") ||
Mokytojai[kel][j].startsWith("N") ) ){
patogiPamoka = j;
isRyto = false;
iter++;
}
j++;
if ( j >= sMo-1 ){ j = 0; iter++; }
}
if (( langoVieta >= 3 ) && ( patogiPamoka >= 3 ) && ( langoVieta < sMo ) && ( patogiPamoka < sMo )){ // Jei rasta patogi paskaita ir langas tai vykdomas perstatymas
if ( !perstatymas ( kel, langoVieta, patogiPamoka, isRyto )){ // Pradinio tvarkarascio tikrinimas, jei atsidobo arba manote, kad nereikes uzkomentuoti sekancia eilute.
kurKlaida = ArGerasTvarkarastis ( kel, langoVieta, patogiPamoka );
if ( kurKlaida > -1 ){ MessageBox msg = new MessageBox(" Schedule error ", klaidosTekstas);
msg.show();
kurKlaida = -1;
}
return false;
}
else return true;
}
else return false;
}

//----- Sukeicia langa su patogia paskaita, jeigu tai nepriestarauja apribojimams -------------------------

private boolean perstatymas ( int kel, int langoVieta, int patogiPamoka, boolean isRyto )
{ int langoPamoka = ( langoVieta - 2 ) % 7;
if ( langoPamoka == 0 ) langoPamoka = 7;
int langoDiena = (int)Math.ceil ((double)(langoVieta - 2) / 7);
int pamokosPamoka = ( patogiPamoka - 2 ) % 7;
if ( pamokosPamoka == 0 ) pamokosPamoka = 7;
int pamokosDiena = (int)Math.ceil ((double)(patogiPamoka - 2) / 7);

// Cia tikrina ar nera priestaravimu apribojimams
if ( tikrintiPriestaravimus ( kel, langoVieta, patogiPamoka )){ // Priestaravimu nera, galima keisti. Vykdomas sukeitimas
switch (langoDiena){ case 1: Mokytojai[kel][langoVieta] = "P"; break;
case 2: Mokytojai[kel][langoVieta] = "A"; break;
case 3: Mokytojai[kel][langoVieta] = "T"; break;
case 4: Mokytojai[kel][langoVieta] = "K"; break;
case 5: Mokytojai[kel][langoVieta] = "N"; break;
}
Mokytojai[kel][langoVieta] = Mokytojai[kel][langoVieta].concat(String.valueOf(pamokosPamoka));
Mokytojai[kel][langoVieta] = Mokytojai[kel][langoVieta].concat(Mokytojai[kel][patogiPamoka].substring(2));
Mokytojai[kel][patogiPamoka] = "Q";
int zenklas;
if ( isRyto ) zenklas = 1;
else zenklas = -1;
while ( (Mokytojai[kel][patogiPamoka+zenklas] == "X") && (patogiPamoka+zenklas < sMo) ) Mokytojai[kel][patogiPamoka+zenklas] = "Q"; return true;
}
else return false;
}

//------------------------------- Tikrina ar nera priestaravimu ------------------------

// Esant priestaravimams grazinama FALSE reiksme, kitu atveju TRUE
private boolean tikrintiPriestaravimus ( int kel, int langoVieta, int patogiPamoka )
{ String s = new String(Mokytojai[kel][patogiPamoka].substring(2));
boolean isKaires = false;
boolean isDesines = false;
for ( int i = 0; i < eMo; i++ ){ // Tikrinama ar neatsiras mokiniams lango, jei isimsime sita rasta patogia pamoka
if ( Mokytojai[i][patogiPamoka-1].length() >= 4 ) if ( s.equals(Mokytojai[i][patogiPamoka-1].substring(2)) ) isDesines = true; if ( Mokytojai[i][patogiPamoka+1].length() >= 4 ) if ( s.equals(Mokytojai[i][patogiPamoka+1].substring(2)) ) isKaires = true; // O gal jau sita klase turi paskaita mokytojo lango metu????
if ( Mokytojai[i][langoVieta].length() >= 4 ) if ( s.equals(Mokytojai[i][langoVieta].substring(2)) ) return false; // Negali vykti dvi to pacio dalyko paskaitos is eiles. Patikrinami ir kiti mokytojai, destantys ta dalyka.
if ( Mokytojai[i][langoVieta-1].length() >= 4 ){ if ( Mokytojai[kel][1].equals(Mokytojai[i][1]) && ( kel != i ) && s.equals(Mokytojai[i][langoVieta-1].substring(2)) ) return false; if ( ( kel == i ) && ( langoVieta-1 != patogiPamoka ) && s.equals(Mokytojai[i][langoVieta-1].substring(2)) ) return false; }
O ar tas pats destytojas neturi sekancios pamokos tai klasei????
if ( Mokytojai[i][langoVieta+1].length() >= 4 ){ if ( Mokytojai[kel][1].equals(Mokytojai[i][1]) && ( kel != i ) && s.equals(Mokytojai[i][langoVieta+1].substring(2)) ) return false; if ( ( kel == i ) && ( langoVieta+1 != patogiPamoka ) && s.equals(Mokytojai[i][langoVieta+1].substring(2)) ) return false; }
if ( isKaires && isDesines ) return false;
}
return true;
}

//------------------------------- Tikrina ar geras pradinis tvarkarastis ------------------------

// Klaidos atveju grazina stulpeli, kuriame buvo rasta klaida, arba -1 kitu atveju. Atsizvelgiama i pataisymus nurodytus dokumentacijoje apie isskirtines pamokas.
private int ArGerasTvarkarastis ( int kel, int langoVieta, int patogiPamoka )
{ String s = new String (Mokytojai[kel][patogiPamoka].substring(2));
char d = Mokytojai[kel][patogiPamoka].charAt(0);
int pradzia = 0;
int pabaiga = 0;
int bug = 0;
int kk;
int [] mas = new int [8];
// Tikrinama ar tik ta klase neturi langu nurodyta diena
switch (d){ case 'P': pradzia = 3; pabaiga = 10; break;
case 'A': pradzia = 10; pabaiga = 17; break;
case 'T': pradzia = 17; pabaiga = 24; break;
case 'K': pradzia = 24; pabaiga = 31; break;
case 'N': pradzia = 31; pabaiga = 38; break;
}
for ( int k = 0; k < 8; k++ ) mas[k] = 0; for ( int i = 0; i < eMo; i++ ) for ( int j = pradzia; j < pabaiga; j++ ) if ( Mokytojai[i][j].length() >= 4 ) if ( s.equals(Mokytojai[i][j].substring(2))){ kk = (j-3)%7;
if (( kk == 0 ) && ( j != pradzia )) kk = 6; mas[kk+1] = 1;
}
for ( int k = 0; k < 7; k++ ) if ( mas[k] != mas[k+1] ) bug++; if ( bug > 2 ){ klaidosTekstas = "<"+ s + "> class has windows on day <" + d + ">\n";
return patogiPamoka;
}

// Ar nera dvieju paskaitu tuo pat metu... nepersiplesi gi
boolean klaida = false;
for ( int i = 0; i < eMo; i++ ){ if ( Mokytojai[i][patogiPamoka].length() >= 4 ) if ( s.equals(Mokytojai[i][patogiPamoka].substring(2)) && !Mokytojai[kel][1].equals(Mokytojai[i][1]) &&
!(Mokytojai[kel][2].equals("R") || Mokytojai[kel][2].equals("B")) &&
!(Mokytojai[i][2].equals("R") || Mokytojai[i][2].equals("B"))){ klaidosTekstas = "<"+ s + "> class has two lessons at the same time. Position (" + String.valueOf(kel+1) + "," + String.valueOf(patogiPamoka+1)+")\n";
return patogiPamoka;
}
// O gal yra kelios to paties dalyko pamokos iseiles...???
if ( Mokytojai[i][patogiPamoka-1].length() >= 4 ){ if ( Mokytojai[kel][1].equals(Mokytojai[i][1]) && s.equals(Mokytojai[i][patogiPamoka-1].substring(2)) &&
!(Mokytojai[kel][2].equals("D") || Mokytojai[kel][2].equals("B")) &&
!(Mokytojai[i][2].equals("D") || Mokytojai[i][2].equals("B"))) klaida = true;
}
if ( Mokytojai[i][patogiPamoka+1].length() >= 4 ){ if ( Mokytojai[kel][1].equals(Mokytojai[i][1]) && s.equals(Mokytojai[i][patogiPamoka+1].substring(2)) &&
!(Mokytojai[kel][2].equals("D") || Mokytojai[kel][2].equals("B")) &&
!(Mokytojai[i][2].equals("D") || Mokytojai[i][2].equals("B"))) klaida = true;
}
}
if ( klaida ){ klaidosTekstas = "<"+ s + "> class has two lessons one after another. Position (" + String.valueOf(kel+1) + "," + String.valueOf(patogiPamoka+1)+")\n";
return patogiPamoka;
}
return -1;
}

//------------------------------- Skaiciuoja kiek yra langu turi esamas tvarkarastis------------------------

private int geriausias ()
{ int langai = 0;
for ( int i = 0; i < eMo; i++ ) for ( int j = 3; j < sMo; j++ ) if ( Mokytojai[i][j].equals ( C_LANGAS ) ) langai++; return langai;
}
};