- package KKProgramming;
- import java.util.ArrayList;
- import Jama.Matrix;
- public class Obliczenia {
- private double r;
- private double mi;
- private double epsilon;
- private double alfa;
- private double t0;
- private double gamma;
- private double beta;
- private ArrayList<Zasob> supplies;
- private ArrayList<Matrix> buildings;
- public final static int BACKTRACKING = 1;
- public final static int GOLDENRATIO = 2;
- public final static int HOOK = 3;
- // statystyki
- public long hookAll = 0;
- public long hookWork = 0;
- public double hookResult = 0.;
- public int interiorAll = 0;
- public double newtonAv = 0.;
- public int newtonAll = 0;
- public double interiorResult = 0;
- public void clearBuildings() {
- buildings.clear();
- }
- public ArrayList<Matrix> getBuild() {
- return buildings;
- }
- public void setVariables(double r, double t, double gamma, double epsilon,
- double mi, double alpha) {
- this.r = r;
- this.t0 = t;
- this.gamma = gamma;
- this.epsilon = epsilon;
- this.mi = mi;
- this.alfa = alpha;
- }
- private Matrix arrayToMatrix(ArrayList<Matrix> array) {
- int n = array.size();
- Matrix m = new Matrix(n * 2, 1);
- int i = 0;
- for (Matrix a : array) {
- m.set(2 * i, 0, a.get(0, 0));
- m.set(2 * i + 1, 0, a.get(1, 0));
- i++;
- }
- return m;
- }
- private ArrayList<Matrix> matrixToArray(Matrix matrix) {
- ArrayList<Matrix> array = new ArrayList<Matrix>();
- for (int i = 0; i < matrix.getRowDimension(); i++) {
- Matrix m = new Matrix(2, 1);
- m.set(0, 0, matrix.get(i, 0));
- m.set(1, 0, matrix.get(++i, 0));
- array.add(m);
- }
- return array;
- }
- public ArrayList<Matrix> startInteriorPoint(int alghoritm) {
- interiorAll = 0;
- newtonAv = 0.;
- newtonAll = 0;
- int n = buildings.size();
- Matrix temp = arrayToMatrix(buildings);
- double t = t0;
- while (((double) n) / t > epsilon) {
- interiorAll++;
- t = t * mi;
- temp = newton(temp, t, alghoritm);
- }
- buildings = matrixToArray(temp);
- // for(Matrix b: buildings){
- // System.out.println(b.get(0,0)+" "+b.get(1,0));
- // }
- newtonAv = (double) newtonAll / interiorAll;
- interiorResult = o(temp);
- return buildings;
- }
- public double o(Matrix arg) {
- int p = 2;
- double res = 0D;
- for (int i = 0; i < this.supplies.size(); i++) {
- Zasob o = this.supplies.get(i);
- double norm = Math.sqrt(normSquare(arg.get(p, 0),
- arg.get(p + 1, 0), o.getX(), o.getY()));
- res += o.getA() * g(norm - o.getR());
- p += 2;
- }
- return res;
- }
- private double g(double x) {
- return 0.5D * (x + Math.sqrt(x * x + gamma));
- }
- private double minimize(int alg, Matrix x, Matrix dX, double t) {
- switch (alg) {
- case BACKTRACKING:
- return backtracking(x, dX, t);
- case GOLDENRATIO:
- return goldenRatio(x, dX, t);
- default:
- return 0;
- }
- }
- public Matrix newton(Matrix start, double t, int alghoritm) {
- Matrix temp = (Matrix) start.clone();
- double gradNorm;
- double ni;
- do {
- Matrix gradient = gradient(temp, t);
- Matrix hessian = hessian(temp, t);
- Matrix hessianInv = hessian.inverse();
- Matrix hessianInvXgradient = hessianInv.times(gradient);
- gradNorm = gradient.transpose().times(hessianInvXgradient)
- .get(0, 0);
- hessianInvXgradient = hessianInvXgradient.times(-1.0);
- ni = minimize(alghoritm, temp, hessianInvXgradient, t);
- temp = temp.plus(hessianInvXgradient.times(ni));
- } while (gradNorm >= epsilon && ni >= 1.0E-8D && newtonAll++ < 10000);
- return temp;
- }
- private double gt(Matrix x, double t) {
- double ogran = 0D;
- int p = 2;
- for (int i = 0; i < supplies.size(); i++) {
- double normKwa = normSquare(x.get(p, 0), x.get(p + 1, 0),
- x.get(0, 0), x.get(1, 0));
- ogran += Math.log(r * r - normKwa);
- p += 2;
- }
- return t * o(x) - ogran;
- }
- private double normSquare(double x1, double x2, double y1, double y2) {
- return (x1 - y1) * (x1 - y1) + (x2 - y2) * (x2 - y2);
- }
- private double backtracking(Matrix start, Matrix dX, double t) {
- Matrix gradient = gradient(start, t).transpose();
- Matrix step = gradient.times(dX);
- double ni = 1;
- double newVal;
- do {
- ni *= beta;
- Matrix newStart = start.plus(dX.times(ni));
- newVal = gt(newStart, t);
- } while ((Double.isNaN(newVal))
- || (newVal > gt(start, t) + alfa * ni * step.get(0, 0)));
- System.out.println(ni);
- return ni;
- }
- private double goldenRatio(Matrix start, Matrix dX, double t) {
- double alfa = 0.618;
- double a = 0;
- double b = 1;
- double norm = dX.norm2();
- double lambda = a + (1 - alfa) * (b - a);
- double mi = a + alfa * (b - a);
- while ((b - a) * norm > epsilon) {
- double left = gt(start.plus(dX.times(lambda)), t);
- double right = gt(start.plus(dX.times(mi)), t);
- if (left > right) {
- a = lambda;
- lambda = mi;
- mi = a + alfa * (b - a);
- } else {
- b = mi;
- mi = lambda;
- lambda = a + (1 - alfa) * (b - a);
- }
- }
- return a / 2 + alfa * b / 2;
- }
- private Matrix gradient(Matrix m, double t) {
- int n = buildings.size();
- Matrix res = new Matrix(2 * n, 1);
- double zeroX = 0D;
- double zeroY = 0D;
- int p = 2;
- for (int i = 0; i < n - 1; i++) {
- double norm2 = normSquare(m.get(p, 0), m.get(p + 1, 0),
- m.get(0, 0), m.get(1, 0));
- zeroX += 2.0D * (m.get(p, 0) - m.get(0, 0)) / (r * r - norm2);
- zeroY += 2.0D * (m.get(p + 1, 0) - m.get(1, 0)) / (r * r - norm2);
- p += 2;
- }
- res.set(0, 0, -zeroX);
- res.set(1, 0, -zeroY);
- p = 2;
- for (int i = 0; i < n - 1; i++) {
- Zasob o = supplies.get(i);
- double norm2X = normSquare(m.get(p, 0), m.get(p + 1, 0),
- m.get(0, 0), m.get(1, 0));
- double norm2Z = normSquare(m.get(p, 0), m.get(p + 1, 0), o.getX(),
- o.getY());
- double sqrtnorm2Z = Math.sqrt(norm2Z);
- double x1 = t * o.getA() * g1(sqrtnorm2Z - o.getR()) / sqrtnorm2Z;
- double x2 = 2.0D / (r * r - norm2X);
- double X = x1 * (m.get(p, 0) - o.getX()) + x2
- * (m.get(p, 0) - m.get(0, 0));
- double Y = x1 * (m.get(p + 1, 0) - o.getY()) + x2
- * (m.get(p + 1, 0) - m.get(1, 0));
- res.set(p, 0, X);
- res.set(p + 1, 0, Y);
- p += 2;
- }
- return res;
- }
- private double g1(double x) {
- return 0.5 * (x / Math.sqrt(x * x + gamma)) + 0.5;
- }
- public Matrix hessian(Matrix arg, double t) {
- Matrix res = new Matrix(2 * this.supplies.size() + 2,
- 2 * this.supplies.size() + 2);
- double zeroXX = 0D;
- double zeroYY = 0D;
- double zeroXY = 0D;
- int p = 2;
- for (int i = 0; i < this.supplies.size(); i++) {
- double normKwa = r
- * r
- - normSquare(arg.get(p, 0), arg.get(p + 1, 0),
- arg.get(0, 0), arg.get(1, 0));
- double currXX = 4.0D / (normKwa * normKwa)
- * (arg.get(p, 0) - arg.get(0, 0))
- * (arg.get(p, 0) - arg.get(0, 0)) + 2.0D / normKwa;
- double currYY = 4.0D / (normKwa * normKwa)
- * (arg.get(p + 1, 0) - arg.get(1, 0))
- * (arg.get(p + 1, 0) - arg.get(1, 0)) + 2.0D / normKwa;
- double currXY = 4.0D / (normKwa * normKwa)
- * (arg.get(p, 0) - arg.get(0, 0))
- * (arg.get(p + 1, 0) - arg.get(1, 0));
- res.set(p, 0, -currXX);
- res.set(0, p, -currXX);
- res.set(p + 1, 1, -currYY);
- res.set(1, p + 1, -currYY);
- res.set(p, 1, -currXY);
- res.set(1, p, -currXY);
- res.set(p + 1, 0, -currXY);
- res.set(0, p + 1, -currXY);
- zeroXX += currXX;
- zeroYY += currYY;
- zeroXY += currXY;
- p += 2;
- }
- res.set(0, 0, zeroXX);
- res.set(1, 1, zeroYY);
- res.set(1, 0, zeroXY);
- res.set(0, 1, zeroXY);
- p = 2;
- for (int i = 0; i < this.supplies.size(); i++) {
- Zasob o = (Zasob) this.supplies.get(i);
- double norm2X = normSquare(arg.get(p, 0), arg.get(p + 1, 0),
- arg.get(0, 0), arg.get(1, 0));
- double norm2Z = normSquare(arg.get(p, 0), arg.get(p + 1, 0),
- o.getX(), o.getY());
- double sqrtnorm2Z = Math.sqrt(norm2Z);
- double cubenormZ = sqrtnorm2Z * sqrtnorm2Z * sqrtnorm2Z;
- double x1 = t
- * o.getA()
- * (g2(sqrtnorm2Z - o.getR()) * sqrtnorm2Z - g1(sqrtnorm2Z
- - o.getR())) / cubenormZ;
- double x2 = t * o.getA() * g1(sqrtnorm2Z - o.getR()) / sqrtnorm2Z;
- double x3 = 4.0D / ((r * r - norm2X) * (r * r - norm2X));
- double x4 = 2.0D / (r * r - norm2X);
- double wartXX = x1 * (arg.get(p, 0) - o.getX())
- * (arg.get(p, 0) - o.getX()) + x2 + x3
- * (arg.get(p, 0) - arg.get(0, 0))
- * (arg.get(p, 0) - arg.get(0, 0)) + x4;
- double wartYY = x1 * (arg.get(p + 1, 0) - o.getY())
- * (arg.get(p + 1, 0) - o.getY()) + x2 + x3
- * (arg.get(p + 1, 0) - arg.get(1, 0))
- * (arg.get(p + 1, 0) - arg.get(1, 0)) + x4;
- double wartXY = x1 * (arg.get(p, 0) - o.getX())
- * (arg.get(p + 1, 0) - o.getY()) + x3
- * (arg.get(p, 0) - arg.get(0, 0))
- * (arg.get(p + 1, 0) - arg.get(1, 0));
- res.set(p, p, wartXX);
- res.set(p + 1, p + 1, wartYY);
- res.set(p, p + 1, wartXY);
- res.set(p + 1, p, wartXY);
- p += 2;
- }
- return res;
- }
- private double g2(double x) {
- double sqrt = Math.sqrt(x * x + gamma);
- return 0.5 * (1.0 / sqrt - x * x / (sqrt * sqrt * sqrt));
- }
- }