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;
}
};