// Dr. M. Turhan ÇOBAN
//
// EGE University School of Engineering, Mechanical Engineering Department
// package : Numerical analysis package
// subject : optimization
// group   : Monte-Carlo optimisation(maximum) Algorithms 
// monte_carlo_opt Class
// class selects random points at the given area and selects the best
// results found
// 

import java.util.*;
import java.io.*;

abstract class f_xj extends Mathd
{
  // single function  multi independent variable
  // a single value is returned indiced to equation_ref
  // example f[0]=x[0]+sin(x[1])
  //         f[1]=x[0]*x[0]-x[1]
  // func(x,1) returns the value of f[1]
  // func(x,0) returns the value of f[0]

  abstract double func(double x[]);
}

public class monte_carlo_opt extends Object
{
int N;
public double max[];
public double min[];        
public double x;

public monte_carlo_opt(int Ni,double imin[],double imax[])
{
 max=new double[imin.length];
 min=new double[imin.length];	
 N=Ni;
 int n=imin.length;
 for(int i=0;i<n;i++)
 {min[i]=imin[i];max[i]=imax[i];}	
}

public double[] monte_carlo_max(f_xj fi)
{
 int n=min.length;
 double x[]=new double[n];
 double xmax[]=new double[n];
 double max_number=-1e99;
 double f;
 for(int k=0;k<N;k++)
 {
 for(int i=0;i<n;i++)
 {x[i]=min[i]+(max[i]-min[i])*Math.random();}
 f=fi.func(x); 
 if(f>max_number) 
   {  max_number=f;
      for(int i=0;i<n;i++)
         {xmax[i]=x[i];}
   }	
 }
 return xmax; 
}
}
