import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Time;
import java.util.LinkedList;
import javax.imageio.ImageIO;
@SuppressWarnings("serial")
public class Symulacja extends Canvas implements MouseListener,Runnable {
// Klasa rysujaca symulacje
//27 kwietnia-dodanie rysowanie planet i punktu koncowego
//27 kwietnia-dodana obsluga drag&drop
//27 kwietnia-dodano watki
//27 kwietnia-dodano animacje toru lotu
//28 kwietnia-dodano checkpoint'y
BufferedImage stars;
static Punkt koncowy;
Planeta lista_planet[];
static Punkt lista_punktow[];
static int masa_statku;
int minIndex=0;
//obsluga drag&drop
int x;
int y;
boolean activeK=false;
//obsluga symulacji
static Thread watek;
static Punkt stara_lista[];
int count=0;
//obsluga checkpointow
long time;
int ID;
CheckPoint lista_check[]= new CheckPoint[10000];
int wybor=1;
double minOdleglosc=0;
BufferedImage listaObrazkow[] = new BufferedImage[5];
public Symulacja(Planeta[] lista_planet){
this.lista_planet=lista_planet;
setSize(new Dimension(800, 750));
try {
stars = ImageIO.read(new File(
"C:\\Users\\tnt\\Desktop\\hubbledeepfield.jpg"));
} catch (IOException e) {
}
watek = new Thread(this, "MSID Sim");
}
public void newThread(){
watek = new Thread(this, "MSID Sim");
}
public void paint(Graphics g) {
addMouseListener(this);
super.paint(g);
setBackground(Color.black);
g.drawImage(stars, 0, 0, null);
//rysowanie planet
if(lista_planet!=null){
for(int i=0;i<lista_planet.length;i++){
try{g.setColor(Color.gray);
g.fillArc(lista_planet[i].x-25, lista_planet[i].y-25, 50, 50, 0, 360);
g.setColor(Color.green);
g.drawString("X:"+lista_planet[i].x,lista_planet[i].x-10 , lista_planet[i].y-7);
g.drawString("Y:"+lista_planet[i].y,lista_planet[i].x-10 , lista_planet[i].y+3);
g.drawString("M:"+lista_planet[i].m,lista_planet[i].x-15 , lista_planet[i].y+13);} catch (Exception e){}
}
}
//rysowanie punktu koncowego
if(koncowy!=null){
g.setColor(Color.red);
g.drawLine((int)koncowy.x-10, (int)koncowy.y-10, (int)koncowy.x+10,(int) koncowy.y+10);
g.drawLine((int)koncowy.x+10, (int)koncowy.y-10, (int)koncowy.x-10, (int)koncowy.y+10);
g.drawString("Punkt koncowy", (int)koncowy.x+10, (int)koncowy.y+2);
}
//rysowanie starej,zapamietanej trasy lotu
// if(stara_lista!=null){
// for(int i=0;i<count-2;i++){
// g.setColor(Color.green);
// g.drawLine((int)stara_lista[i].x,(int) stara_lista[i].y, (int)stara_lista[i+1].x, (int)stara_lista[i+1].y);
//
// }
//
// }
}
//metoda do testowania,tworza trase lotu
public void trasaExp(){
lista_punktow=Function.pkt;
}
public static void setPP(Punkt p) {
koncowy=p;
//lista_planet=lista;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@SuppressWarnings("deprecation")
@Override
public void mousePressed(MouseEvent e) {
x=e.getX();
y=e.getY();
watek.stop();
Clock.watek.stop();
//do planet
for(int i=0;i<lista_planet.length;i++){
if(lista_planet[i].x-20<x && lista_planet[i].x+20>x && lista_planet[i].y-20<y && lista_planet[i].y+20>y){
lista_planet[i].active=true;
break;
}
}
//do punktu
if(koncowy.x-10<x && koncowy.x+10>x && koncowy.y-10<y && koncowy.y+10>y){
activeK=true;
}
}
@Override
public void mouseReleased(MouseEvent e) {
x=e.getX();
y=e.getY();
//do planet
for(int i=0;i<lista_planet.length;i++){
if(lista_planet[i].active==true){
//System.out.println("switch checked");
lista_planet[i].x=x;
lista_planet[i].y=y;
lista_planet[i].active=false;
repaint();
}
}
//do punktu
if(activeK==true){
koncowy.x=x;
koncowy.y=y;
activeK=false;
repaint();
}
}
@SuppressWarnings("static-access")
@Override
public void run() {
stara_lista = new Punkt[Function.pkt.length];
//System.out.println("RUNNING");
count=0;
ID=1;
for(int i=0;i<Function.pkt.length;i++){
if(Function.pkt[i+1]==null){
break;
}
if(Math.abs(Function.pkt[i].x-koncowy.x)<minOdleglosc+1 && Math.abs(Function.pkt[i].y-koncowy.y)<minOdleglosc+1){
break;
}
//wylaczenie symulacji przy min wartosci funkcji punkcie
Graphics g = getGraphics();
g.setColor(Color.green);
g.drawLine((int)lista_punktow[i].x, (int)lista_punktow[i].y, (int)lista_punktow[i+1].x, (int)lista_punktow[i+1].y);
stara_lista[i] = new Punkt(lista_punktow[i].x,lista_punktow[i].y);
count++;
//chekpointy
if(count%40==0){
g.fillArc((int)lista_punktow[i].x-5, (int)lista_punktow[i].y-5, 10, 10, 0, 360);
//g.drawString("X:"+(int)lista_punktow[i].x, (int)lista_punktow[i].x+4, (int)lista_punktow[i].y);
//g.drawString("Y:"+(int)lista_punktow[i].y, (int)lista_punktow[i].x+35, (int)lista_punktow[i].y);
lista_check[ID-1]= new CheckPoint(ID, (int)lista_punktow[i].x, i, 0, 0, time/1000000000);
ID++;
//System.out.println(time/100000000);
Clock.checkpointC++;
}
Clock.odleglosc=odlegloscPrzebyta(lista_punktow,Clock.odleglosc,i);
Clock.odleglosc_od_pkt=odlegloscOdPunktu(lista_punktow, i);
try {
watek.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Clock.watek.stop();
}
static public double odlegloscPrzebyta(Punkt[] lista, double odlegosc,int i){
int x=Math.abs((int)lista[i+1].x-(int)lista[i].x);
int y=Math.abs((int)lista[i+1].y-(int)lista[i].y);
odlegosc=odlegosc+(Math.sqrt((x*x)+(y*y)));
return odlegosc;
}
static public double odlegloscOdPunktu(Punkt[] lista,int i){
int x=Math.abs((int)lista[i].x-(int)koncowy.x);
int y=Math.abs((int)lista[i].y-(int)koncowy.y);
double dystans=(Math.sqrt((x*x)+(y*y)));
return dystans;
}
public void startSim(){
//kat i masa
switch(wybor){
case 1:HookJeeves(); break;
case 2:metodaNewtona(); break;
case 3:RunningAlgoritm(); break;
case 4:uruchomBezMetody(); break;
}
watek.start();
}
int mass;
int kat;
//METODA SYMPLEKSU
public void RunningAlgoritm(){
double a = 1;
double b = 0.5;
double gamma = 2;
minIndex=0;
double minWart=100000000;
double epsilon = 0.3;
//wyszukanie planety
for(int i=0;i<5;i++){
double xx=Math.abs(lista_planet[i].x);
double yy=Math.abs(lista_planet[i].y);
double r = Math.pow(xx*xx+yy*yy, 0.5);
if(r<minWart){
minWart=r;
minIndex=i;
}
}
//wartosci poczatkowe
// mass=10*10;
// kat=315;
mass=0;
kat=0;
//wiecholki simplexu startowe
Punkt[] P0 = new Punkt[3];
P0[0]= new Punkt(0,0);
P0[1]= new Punkt(0,10000);
P0[2]= new Punkt(-90,0);
//min i max
int max = 0;
int min = 0;
int count =0;
//wartosci a punktach
double PW0=0;
double PW1=0;
double PW2=0;
//1 repeat
double suma = 0;
while(true){
//2 //obliczenia wartosci funkcji w wierzcholkach simplexu
PW0=GetMin(P0[0].x, P0[0].y);
PW1=GetMin(P0[1].x, P0[1].y);
PW2=GetMin(P0[2].x, P0[2].y);
//3 wyznaczanie Pmax i Pmin
if(PW0>PW1 && PW0>PW2){
max=0;
}
if(PW1>PW0 && PW1>PW2){
max=1;
}
if(PW2>PW0 && PW2>PW1){
max=2;
}
///////////////////////////
if(PW0<PW1 && PW0<PW2){
min=0;
}
if(PW1<PW0 && PW1<PW2){
min=1;
}
if(PW2<PW0 && PW2<PW1){
min=2;
}
//4 wyznaczenie srodka ciezkosci
Punkt PWciezkosci= new Punkt(0,0);
double x = 0;
double y = 0;
for(int i=0;i<3;i++){
if(i!=max){
x=x+P0[i].x;
y=y+P0[i].y;
}
}
PWciezkosci.x=x/2;
PWciezkosci.y=y/2;
//5 wyznaczanie punktu odbicia
Punkt PWOdbicia = new Punkt(0,0);
PWOdbicia.x=PWciezkosci.x+a*(PWciezkosci.x-P0[max].x);
PWOdbicia.y=PWciezkosci.y+a*(PWciezkosci.y-P0[max].y);
// 6 jesli wartosc funncji celu w punkcie odbicia mniejsza od wartosc w pkt min
Punkt PWE = new Punkt(0,0);
if(GetMin(PWOdbicia.x, PWOdbicia.y)<GetMin(P0[min].x, P0[min].y)){
//7 jesli mniejsze to liczymy punkt expansji
PWE.x=PWciezkosci.x+gamma*(PWOdbicia.x-PWciezkosci.x);
PWE.y=PWciezkosci.y+gamma*(PWOdbicia.y-PWciezkosci.y);
//jesli wartosc funkcji celu w puntke ekspansji jest mniejsze od wartosci w punkcie odbicia
if(GetMin(PWE.x, PWE.y)<GetMin(PWOdbicia.x, PWOdbicia.y)){
//ekspansja
P0[max]= new Punkt(PWE.x, PWE.y);
}else{
P0[max]= new Punkt(PWOdbicia.x, PWOdbicia.y);
}
}else{
if(GetMin(PWOdbicia.x, PWOdbicia.y)>=GetMin(P0[min].x, P0[min].y) && GetMin(PWOdbicia.x, PWOdbicia.y)<GetMin(P0[max].x, P0[max].y) ){
P0[max]=PWOdbicia;
}else{
Punkt PWZ = new Punkt(0,0);
PWZ.x=PWciezkosci.x+b*(P0[max].x-PWciezkosci.x);
PWZ.y=PWciezkosci.y+b*(P0[max].y-PWciezkosci.y);
if(GetMin(PWZ.x, PWZ.y)>=GetMin(P0[max].x, P0[max].y)){
for(int i=0;i<3;i++){
if(i!=min){
P0[i].x=0.5*(P0[i].x+P0[min].x);
P0[i].y=0.5*(P0[i].y+P0[min].y);
}
}
}else{
P0[max]=new Punkt(PWZ.x, PWZ.y);
}
}
}
double zz = 0;
for(int i=0;i<3;i++){
if(i!=min){
double xx=Math.abs(P0[min].x-P0[i].x);
double yy=Math.abs(P0[min].y-P0[i].y);
zz=Math.pow((xx*xx)+(yy*yy), 0.5);
}
}
// System.out.println(zz);
//
// System.out.println(P0[0].x);
// System.out.println(P0[0].y);
// System.out.println();
// System.out.println(P0[1].x);
// System.out.println(P0[1].y);
// System.out.println();
// System.out.println(P0[2].x);
// System.out.println(P0[2].y);
// System.out.println("------------------------------");
//
if(zz<epsilon){
break;
}
count++;
}
System.out.println("Ilosc iteracji "+ count);
trasaExp();
System.out.println("Masa "+ P0[min].y);
System.out.println("Kat "+ P0[min].x);
System.out.println("Odleglosc od celu wynosi "+GetMin(P0[min].x, P0[min].y));
}
public double GetMin(double kat,double mass){
lista_planet[minIndex]= new Planeta(lista_planet[minIndex].x, lista_planet[minIndex].y, mass);
Function g =new Function(kat, mass,lista_planet,minIndex);
minOdleglosc=g.RozpoczecieSymulacji();
return g.odlegloscOdpkt;
}
// METODA NEWTONA
double epsilon = 2;
double d = 4000;
double min_d = 2;
double alfa = 0;
long masa = 0;
int typ_skoku = 7; // 1 to zwieksz alfa, 2 zwieksz mase, 3 zwieksz oba, 4 zmniejsza alfa, 5 zmniejsza mase, 6 zmniejsza oba
int iteration = 0;
LinkedList<MNE_SK> lista_sprawdzen = new LinkedList<MNE_SK>();
public void metodaNewtona() {
minIndex=0;
double minWart=100000000;
//wyszukanie planety
for(int i=0;i<5;i++){
double xx=Math.abs(lista_planet[i].x);
double yy=Math.abs(lista_planet[i].y);
double r = Math.pow(xx*xx+yy*yy, 0.5);
if(r<minWart){
minWart=r;
minIndex=i;
}
}
while (typ_skoku!=0) {
sprawdz_kierunek();
skocz();
sprawdz_wartosc();
iteration++;
//System.out.println("Iteracja glowna programu "+iteration);
// System.out.println("Wartosc funkcji celu "+GetMin(alfa,masa));
if(iteration>2000){break;}
}
System.out.println("Iteracji: "+iteration+" Kat "+alfa+" masa "+masa+" Wartosc funkcji "+GetMin
(alfa,masa));
trasaExp();
}
public void sprawdz_kierunek() {
double w1 = GetMin(alfa, masa);
double w2 = GetMin(alfa + epsilon, masa);
double w3 = GetMin(alfa, masa + epsilon);
double w4 = GetMin(alfa + epsilon, masa + epsilon);
double w5 = GetMin(alfa-epsilon, masa);
double w6 = GetMin(alfa, masa-epsilon);
double w7 = GetMin(alfa-epsilon, masa - epsilon);
MNE_SK sprawdzenie = new MNE_SK(w1, w2, w3, w4, w5, w6, w7);
double min = Math.min(w7, Math.min(w6,Math.min(w5, Math.min(sprawdzenie.skok[1],Math.min(sprawdzenie.skok[2], sprawdzenie.skok[3])))));
if (w1<min) {
typ_skoku = 0;
} else if (min == w2) {
typ_skoku = 1;
} else if (min == w3) {
typ_skoku = 2;
} else if (min == w4){
typ_skoku = 3;
} else if (min == w5){
typ_skoku = 4;
} else if (min == w6){
typ_skoku = 5;
} else {
typ_skoku = 6;
}
sprawdzenie.typ = typ_skoku;
//System.out.println("Typ skoku :"+typ_skoku);
lista_sprawdzen.add(sprawdzenie);
}
public void skocz() {
switch (typ_skoku) {
case 1:
alfa += d;
break;
case 2:
masa += d;
break;
case 3:
alfa += d;
masa += d;
break;
case 4:
alfa -= d;
break;
case 5:
masa -=d;
break;
case 6:
alfa-=d;
masa-=d;
break;
}
}
public void skocz_do_tylu(){
switch (typ_skoku) {
case 1:
alfa -= d;
break;
case 2:
masa -= d;
break;
case 3:
alfa -= d;
masa -= d;
break;
case 4:
alfa+=d;
break;
case 5:
masa+=d;
break;
case 6:
alfa+=d;
masa+=d;
break;
}
}
public void sprawdz_wartosc() {
double wart = GetMin(alfa, masa);
if (wart <= lista_sprawdzen.get(iteration).skok[0]) {
} else {
int i=0;
//System.out.println("Zmniejszanie wartosci D");
while(d>min_d){
// System.out.println("Iteracja zmniejszenia D "+i);
// System.out.println("Wartosc D "+d);
skocz_do_tylu();
zmniejszD();
skocz();
wart = GetMin(alfa, masa);
if (wart < lista_sprawdzen.get(iteration).skok[0]){ break;}
i++;
}
System.out.println("Zmniejszono wartosc D po "+i+" iteracjach do wartosci "+d);
//System.out.println("Zakonczono zmniejszanie wartosci D");
}
}
public void zmniejszD() {
if (d > min_d) {
d -= 2;
}
}
// KONIEC METODY NEWTONA
public void zmienWybor(int wyb){
wybor=wyb;
}
//metoda Hooke'a-Jeevesa z krokiem dyskretnym
double beta = 0.7; //wsp�czynnik zmniejszenia kroku d�ugo�ci
double eps = 0.5; //warunek stopu-minimalna d�ugo�� kroku pr�bnego
int iteracjeHook=0;
public void HookJeeves (){
minIndex=0;
double minWart=100000000;
//wyszukanie planety
for (int i=0;i<5;i++){
double xx=Math.abs(lista_planet[i].x);
double yy=Math.abs(lista_planet[i].y);
double r= Math.pow(xx*xx+yy*yy,0.5);
if(r<minWart){
minWart=r;
minIndex=i;
}
}
double s = 10000; //d�ugo�� kroku
;
Punkt x = algorytmHJ(0, 0, s);
System.out.println("Kat "+x.x+"masa" +x.y+ "Wartosc funkcji "+GetMin(x.x,x.y));
System.out.println("Ilosc iteracji wynosi "+iteracjeHook);
trasaExp();
}
public Punkt algorytmHJ(double alfa, double masa, double s){
Punkt newbase;
Punkt x_3 = new Punkt(alfa,masa);
Punkt x_bazowy;
while(true){
iteracjeHook++;
x_bazowy = new Punkt(x_3.x, x_3.y);//punkt bazowy
Punkt x_min=ProbujHJ(x_bazowy.x, x_bazowy.y, s); //punkty pr�bne
if(GetMin(x_min.x,x_min.y)<GetMin(x_bazowy.x,x_bazowy.y)){
//znalaz�o lepszy punkt
//System.out.println("WESZLO W PIERWSZY WARUNEK");
while(true){
if(x_bazowy.x==x_min.x&&x_bazowy.y==x_min.y){
s=beta*s;
if (s<epsilon){
break;
}
else algorytmHJ(x_min.x, x_min.y, s);
}
newbase = new Punkt(x_bazowy.x, x_bazowy.y);
x_bazowy= new Punkt(x_min.x, x_min.y);
x_3=new Punkt(2*(x_bazowy.x-newbase.x), 2*(x_bazowy.y-newbase.y));
x_3=ProbujHJ(x_3.x, x_3.y, s);
if(GetMin(x_3.x, x_3.y)>=GetMin(x_bazowy.x, x_bazowy.y)){
break;
}
//x_min=new Punkt(x_3.x, x_3.y);
}
x_3= new Punkt(x_bazowy.x, x_bazowy.y);
}
else{s=beta*s;}
if (s<epsilon){
break;
}
}
return x_bazowy;
}
//another try
public Punkt ProbujHJ(double alfa,double masa, double s){
// double fmin = GetMin(alfa, masa);
int n=2;
int i=1;
while(i<n){
if(GetMin(alfa+s, masa)<GetMin(alfa, masa)){
System.out.println("petla pierwsza (alfa+s, masa+s)");
alfa=alfa+s;
// masa=masa+s;
i++;
}
else{
if (GetMin(alfa,masa+(s*1000000))<GetMin(alfa, masa)){
System.out.println("petla druga(alfa, masa+s)");
// alfa=alfa;
masa=masa+(s*1000000);
i++;
}
else{
if(GetMin(alfa,masa-s)<GetMin(alfa, masa)){
System.out.println("petla trzecia (alfa, masa-s)");
alfa=alfa-s;
masa=masa-s;
i++;}
else{
if(GetMin(alfa-s,masa)<GetMin(alfa, masa)){
System.out.println("petla czwarta (alfa-s, masa)");
alfa=alfa-s;
// masa=masa;
// System.out.println("w srodku");
i++;}
else{
// System.out.println("i");
i++;}
}
i++;
}
}
}
Punkt x_min=new Punkt(alfa, masa);
System.out.println("masa "+x_min.y);
return x_min;
}
/*
//etap pr�bny
public Punkt ProbujHJ(double alfa,double masa, double s){
// double fmin = GetMin(alfa, masa);
int n=2;
int i=1;
while(i<n){
if(GetMin(alfa+s, masa+s)<GetMin(alfa, masa)){
alfa=alfa+s;
masa=masa+s;
i++;
}else{
if (GetMin(alfa-s,masa-s)<GetMin(alfa, masa)){
alfa=alfa-s;
masa=masa-s;
i++;
}else{
i++;
}
}
}
Punkt x_min=new Punkt(alfa, masa);
return x_min;
}*/
/*
//v2
public Punkt ProbujHJ(double alfa,double masa, double s){
int n=2;
int i=1;
while(i<n){
if(GetMin(alfa+s, masa)<GetMin(alfa, masa)){
System.out.println("alfa+s ");
// System.out.println("getmin1 "+GetMin(alfa+s, masa));
alfa=alfa+s;
// System.out.println("alfa war1 "+alfa);
if (GetMin(alfa, masa+s)<GetMin(alfa, masa))
{
masa=masa+s;
System.out.println("akuku1+s");
i++;
}
else {
System.out.println("spr1 "+GetMin(alfa, masa-s));
System.out.println("spr2 "+GetMin(alfa, masa));
if (GetMin(alfa, masa-s)<GetMin(alfa, masa)){
// System.out.println("spr1"));
masa=masa-s;
i++;
// System.out.println("akuku2-s"+GetMin(alfa, masa));
}
i++;
}
}
else {
if(GetMin(alfa-s, masa)<GetMin(alfa, masa)){
System.out.println("alfa-s ");
alfa=alfa-s;
System.out.println("alfa war2 "+alfa);
if (GetMin(alfa, masa+s)<GetMin(alfa, masa)){
masa=masa+s;
i++;
}
else {
if (GetMin(alfa, masa-s)<GetMin(alfa, masa)){
masa=masa-s;
i++;
}
}
}
else {
System.out.println("sama masa ");
//System.out.println("alfa war3 "+alfa);
if (GetMin(alfa, masa+(s*10000))<GetMin(alfa, masa)){
masa=masa+(s*10000); i++;
// System.out.println("alfa war3a (masa+s) "+masa);
}
else {
if (GetMin(alfa, masa-s)<GetMin(alfa, masa)){
masa=masa-s; i++;
// System.out.println("alfa war3b (masa-s) "+masa);
}
//System.out.println("alfa war3c (masa) ");
}
i++;
}
}}
System.out.println("koniec_pr�buj "+iteracjeHook);
Punkt x_min=new Punkt(alfa, masa);
System.out.println("x_min.x "+x_min.x+" x_min.y "+x_min.y);
return x_min;
}
*/
long ms=0;
double kt=0;
public void setBM(long m, double k){
ms=m;
kt=k;
}
public void uruchomBezMetody(){
GetMin(ms,kt);
trasaExp();
}
}