// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// Source File Name:   Globt.java

package lt.ktu.gmj.methods;

import java.io.PrintStream;
import java.util.Vector;
import lt.ktu.gmj.*;

// Referenced classes of package lt.ktu.gmj.methods:
//			MethodBase, RandomPoint

public class Globt extends MethodBase
{
	class Random extends Point
	{

		public Random(Point point, double ad[], double ad1[])
		{
			super(point);
			for(int i = 0; i < super.x.length; i++)
				super.x[i] = Math.random();

			for(int j = 0; j < super.x.length; j++)
				super.x[j] = super.x[j] * (ad[j] - ad1[j]) + ad1[j];
		}
	}

	class Subregion
	{
		Vector allPoints;
		double min[];
		double max[];
		double ray1;
		Point center;
		Task task;
		double resultReg;
		Result r;
		Result result;

		public Result getResult()
		{
			return result;
		}

		void setMinMax(Point point, double d, Domain domain)
		{
			for(int i = 0; i < point.x.length; i++)
			{
				System.out.println("domain.max[" + i + "]=" + domain.max[i] + " domain.min[" + i + "]=" + domain.min[i]);
				max[i] = point.x[i] + d;
				if(max[i] > domain.max[i])
					max[i] = domain.max[i];
				min[i] = point.x[i] - d;
				if(min[i] < domain.min[i])
					min[i] = domain.min[i];
				System.out.println("max[" + i + "]=" + max[i] + " min[" + i + "]=" + min[i]);
			}

			System.out.println("=================================");
		}

		boolean verify(Point point, Domain domain)
		{
			boolean flag = true;
			for(int i = 0; i < point.x.length; i++)
				if(domain.max[i] < point.x[i] || point.x[i] < domain.min[i])
					flag = false;

			return flag;
		}

		public Subregion(Vector vector, Task task1, double d, int i, ResultLogger resultlogger, 
				Domain domain, Result result1)
		{
			result = result1;
			task = task1;
			resultReg = 10000D;
			min = new double[((Point)vector.elementAt(0)).x.length];
			max = new double[((Point)vector.elementAt(0)).x.length];
			int j = 0;
			for(int k = 0; k < vector.size(); k++)
			{
				if( resultReg > task1.f((Point)vector.elementAt(k)).fx())
					resultReg = task1.f((Point)vector.elementAt(k)).fx();
				j = k;
			}

			center = (Point)vector.elementAt(j);
			ray1 = d - ((Point)vector.elementAt(0)).distance(center);
			ray1 = d / 2D;
			System.out.println("Spindulys lygus " + ray1);
			setMinMax(center, ray1, domain);
			vector = new Vector();
			for(int l = 0; l < i; l++)
			{
				Random random = new Random(center, max, min);
				if(verify(random, domain))
				{
					vector.addElement(random);
					r = new Result(l, random, task1.f(random));
					resultlogger.log(r);
					if(r.value.fx() < result1.value.fx())
						result = r;
				}
			}

		}
	}


	public int ray1;
	public int ray2;
	Point groupCenter;
	Point nextGroupCenter;
	boolean nextGroup;

	public Globt()
	{
		ray1 = 1;
		ray2 = ray1 + ray1;
		nextGroup = false;
		super.iterations = 1000;
		System.out.println("Globt. (Ignas Namajunas, 1999, Kaunas)");
	}

	private boolean dependentGroup(Point point, Point point1)
	{
		boolean flag = false;
		if(point.distance(point1) <= (double)ray1)
			flag = true;
		else
		if(point.distance(point1) >= (double)ray2 && !nextGroup)
		{
			nextGroup = true;
			nextGroupCenter = point1;
		}
		return flag;
	}

	public Result run(ResultLogger resultlogger, Task task)
	{
		Vector points = new Vector();
		Vector grupes = new Vector();
		Domain domain = task.domain();
		Result result = new Result();
		Result result1 = new Result();
		Result result2 = new Result();
		for(int i = 0; i < super.iterations; i++)
		{
			RandomPoint randompoint = new RandomPoint(domain);
			points.addElement(randompoint);
			result2 = new Result(i, randompoint, task.f(randompoint));
			resultlogger.log(result2);
		}
		result = result2;
		
		groupCenter = (Point)points.elementAt(0);
		//visus nepritapusius po 2n kartu supilam i atskira grupe
		int MaxIterations  = super.iterations;
		int it = 0;
		//
		while(!points.isEmpty() && it < MaxIterations) 
		{
			Vector grupe = new Vector();
			grupe.addElement(groupCenter);
			Vector nepritape = new Vector();
			boolean flag = true;
			//ar teisingai skaidoma i grupes? - pildo grupe, suranda nauja centra ir deda viska prie tos pacios grupes?
			for(int k = 0; k < points.size(); k++)
				if(dependentGroup(groupCenter, (Point)points.elementAt(k)))
					grupe.addElement(new Point((Point)points.elementAt(k)));
				else
				if(flag && nextGroup)
				{
					groupCenter = new Point(nextGroupCenter);
					flag = false;
				} else
				{
					nepritape.addElement(new Point((Point)points.elementAt(k)));
				}
			points = (Vector)nepritape.clone();
			grupes.addElement(grupe);
			nextGroup = false;
			
			it++;
		}
		if(it == MaxIterations && points.size()!=0)
			grupes.addElement(points);
		System.out.println("Buvo sukurta grupiu=" + grupes.size());
		for(int j = 0; j < grupes.size(); j++)
		{
			Subregion subregion = new Subregion((Vector)grupes.elementAt(j), task, ray1, super.iterations, resultlogger, domain, result);
			result = subregion.getResult();
		}
		return result;
	}
}
