/*
 * SimpleSolver.java
 *
 * Created on Ketvirtadienis, 2007, Sausio 25, 17.10
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package Main.algorithms;

import java.util.*;
import lp.*;

public class SimpleSolver extends AbstractAlgorithm {
	public void solve() {
		solve(true);
	}

	public void solve(boolean calculteUV) {
	//	mLog.logn("----------------------------------");
	//	mLog.logn("SOLVING EQUATIONS BEGINS");
		if (calculteUV) {
			mLog.logn("-- MATRIX U");
			calculateMatrixU();
			mLog.logn("-- MATRIX V");
			calculateMatrixV();
		}
              //   indeksas = 10;
                 
		/**
		 * building matrix of Y
		 */

	//	mLog.logn("-- SOLVING X");
		int rows = 3;
		int cols = matrixU.length + 3;
		double[][] matrixSolve = new double[rows][cols];

		for (int i = 0; i < matrixU.length; i++) {
			double sum = 0;
			for (int j = 0; j < matrixU[i].length; j++) {
				sum += matrixU[i][j];
			}

			System.out.println("Sum" + i + ": " + sum);
			matrixSolve[1][i + 1] = sum;
		}
		matrixSolve[1][cols - 2] = -1;
		matrixSolve[1][cols - 1] = 1;

		for (int j = 1; j < cols - 2; j++) {
			matrixSolve[rows - 1][j] = 1;
		}
		matrixSolve[rows - 1][cols - 2] = 0;
		matrixSolve[rows - 1][cols - 1] = 0;

		// create
		solve lpSolve = new solve();
		lprec lpIn = new lprec(0, cols - 1);

		double[] bvalue = new double[cols];
		Arrays.fill(bvalue, 0);

		bvalue[cols - 2] = 1;
		bvalue[cols - 1] = -1;
		// bvalue[1]= 1;

		// max
		lpSolve.set_obj_fn(lpIn, bvalue);
		lpSolve.set_maxim(lpIn);

		// x-y
		for (int i = 1; i < rows - 1; i++)
			lpSolve.add_constraint(lpIn, matrixSolve[i], constant.EQ, 0);

		lpSolve.add_constraint(lpIn, matrixSolve[matrixSolve.length - 1],
				constant.EQ, 1);

		// x1,y1

		int resultInt = lpSolve.solve(lpIn);
		if (resultInt != constant.OPTIMAL) {
			mLog.logn("-- EQUATIONS ALGORITHM FAILED. NOT OPTIMAL");
			setSolved(false);
			// return res;
		} else {
			setSolved(true);
		}

		result = new double[matrixU.length][2];

		for (int i = 0; i < result.length; i++) {
			result[i][0] = lpIn.getBestSolution(lpIn.getRows() + i + 1);
		}

		System.out
				.println("lpIn.getBestSolution(lpIn.getRows()+result.length+1): "
						+ lpIn.getBestSolution(lpIn.getRows() + result.length
								+ 1));
		System.out
				.println("lpIn.getBestSolution(lpIn.getRows()+result.length+2): "
						+ lpIn.getBestSolution(lpIn.getRows() + result.length
								+ 2));

		U = lpIn.getBestSolution(lpIn.getRows() + result.length + 1)
				- lpIn.getBestSolution(lpIn.getRows() + result.length + 2);

		// lpSolve.print_solution(lpIn);

		// double[][] rezultsY= lpSolve.getMatrix();

		/**
		 * building matrix of X
		 */
	//	mLog.logn("-- SOLVING Y");
		matrixSolve = new double[rows][cols];
		for (int i = 0; i < matrixV.length; i++) {
			double sum = 0;
			for (int j = 0; j < matrixV[i].length; j++) {
				sum += matrixV[j][i];
			}
			matrixSolve[1][i + 1] = sum;
		}
		matrixSolve[1][cols - 2] = -1;
		matrixSolve[1][cols - 1] = 1;

		for (int j = 1; j <= cols - 2; j++) {
			matrixSolve[rows - 1][j] = 1;
		}
		matrixSolve[rows - 1][cols - 1] = 0;
		matrixSolve[rows - 1][cols - 2] = 0;

		lpSolve = new solve();
		lpIn = new lprec(0, cols - 1);

		/*
		 * bvalue= new double[cols]; Arrays.fill(bvalue, 0);
		 */

		// max
		lpSolve.set_obj_fn(lpIn, bvalue);
		lpSolve.set_maxim(lpIn);

		// x-y
		for (int i = 0; i < rows - 1; i++)
			lpSolve.add_constraint(lpIn, matrixSolve[i], constant.EQ, 0);

		lpSolve.add_constraint(lpIn, matrixSolve[matrixSolve.length - 1],
				constant.EQ, 1);

		// x1,y1

		resultInt = lpSolve.solve(lpIn);
		if (resultInt != constant.OPTIMAL) {
			mLog.logn("-- EQUATIONS ALGORITHM FAILED. NOT OPTIMAL");
			setSolved(false);
		} else {
			setSolved(true && isSolved());
                        indeksas3 = 5;
		}

		for (int i = 0; i < result.length; i++) {
			result[i][1] = lpIn.getBestSolution(lpIn.getRows() + i + 1);
		}

		V = lpIn.getBestSolution(lpIn.getRows() + result.length + 1)
				- lpIn.getBestSolution(lpIn.getRows() + result.length + 2);

		// lpSolve.print_solution(lpIn);

		// double[][] rezultsX= temp.getMatrix();

		// result= new double[matrixU.length][2];
	//	mLog.logn("-- GENERATING OUTPUT");
		for (int i = 0; i < result.length; i++) {
			if (result[i][0] < 0 || result[i][1] < 0) {
				mLog.logn("-- EQUATION ALGORITHM FAILED");
				setSolved(false);
				break;
			}
		}

		mLog.logn("U = " + Utility.Round(U));
		mLog.logn("V = " + Utility.Round(V));
                
             
                

	//	mLog.logn("SOLVING EQUATIONS ENDS");
	//	mLog.logn("----------------------------------");
		// solveTMP(true);
	}
        
        

	public void solveTMP(boolean calculteUV) {
		mLog.logn("----------------------------------");
		mLog.logn("SOLVING EQUATIONS BEGINS");
		if (calculteUV) {
			mLog.logn("-- MATRIX U");
			calculateMatrixU();
			mLog.logn("-- MATRIX V");
			calculateMatrixV();
		}

		/**
		 * building matrix of Y
		 */

		mLog.logn("-- SOLVING X");
		int rows = matrixU.length + 2;
		int cols = matrixU.length * 2 + 3;
		double[][] matrixSolve = new double[rows][cols];

		int k;
		for (int i = 1; i < rows - 1; i++) {
			k = 1;

			for (int j = 1; j < cols - 2; j += 2, k++) {
				matrixSolve[i][j] = matrixU[k - 1][i - 1];
				matrixSolve[i][j + 1] = -matrixU[k - 1][i - 1];
			}
			matrixSolve[i][cols - 1] = -1;
			matrixSolve[i][cols - 2] = 1;
		}

		for (int j = 1; j < cols - 2; j += 2) {
			matrixSolve[rows - 1][j] = 1;
			matrixSolve[rows - 1][j + 1] = -1;
		}
		matrixSolve[rows - 1][cols - 1] = 0;
		matrixSolve[rows - 1][cols - 2] = 0;

		// create
		solve lpSolve = new solve();
		lprec lpIn = new lprec(0, cols - 1);

		double[] bvalue = new double[cols];
		Arrays.fill(bvalue, 0);

		bvalue[cols - 1] = 1;
		bvalue[cols - 2] = -1;
		// bvalue[1]= 1;

		// max
		lpSolve.set_obj_fn(lpIn, bvalue);
		lpSolve.set_maxim(lpIn);

		// x-y
		for (int i = 1; i < rows - 1; i++)
			lpSolve.add_constraint(lpIn, matrixSolve[i], constant.EQ, 0);

		lpSolve.add_constraint(lpIn, matrixSolve[matrixSolve.length - 1],
				constant.EQ, 1);

		// x1,y1

		int resultInt = lpSolve.solve(lpIn);
		if (resultInt != constant.OPTIMAL) {
			mLog.logn("-- EQUATIONS ALGORITHM FAILED. NOT OPTIMAL");
			setSolved(false);
			// return res;
		} else {
			setSolved(true);
		}

		result = new double[matrixU.length][2];

		k = 1;
		for (int i = 0; i < result.length; i++, k += 2) {
			result[i][0] = lpIn.getBestSolution(lpIn.getRows() + k)
					- lpIn.getBestSolution(lpIn.getRows() + k + 1);
		}

		U = lpIn.getBestSolution(lpIn.getRows() + k + 1)
				- lpIn.getBestSolution(lpIn.getRows() + k);

		// lpSolve.print_solution(lpIn);

		// double[][] rezultsY= lpSolve.getMatrix();

		/**
		 * building matrix of X
		 */
		mLog.logn("-- SOLVING Y");
		matrixSolve = new double[rows][cols];
		for (int i = 1; i < rows - 1; i++) {
			k = 1;
			for (int j = 1; j < cols - 2; j += 2, k++) {
				matrixSolve[i][j] = matrixV[i - 1][k - 1];
				matrixSolve[i][j + 1] = -matrixV[i - 1][k - 1];
			}
			matrixSolve[i][cols - 1] = -1;
			matrixSolve[i][cols - 2] = 1;
		}

		for (int j = 1; j <= cols - 2; j += 2) {
			matrixSolve[rows - 1][j] = 1;
			matrixSolve[rows - 1][j + 1] = -1;
		}
		matrixSolve[rows - 1][cols - 1] = 0;
		matrixSolve[rows - 1][cols - 2] = 0;

		lpSolve = new solve();
		lpIn = new lprec(0, cols - 1);

		/*
		 * bvalue= new double[cols]; Arrays.fill(bvalue, 0);
		 */

		// max
		lpSolve.set_obj_fn(lpIn, bvalue);
		lpSolve.set_maxim(lpIn);

		// x-y
		for (int i = 0; i < rows - 1; i++)
			lpSolve.add_constraint(lpIn, matrixSolve[i], constant.EQ, 0);

		lpSolve.add_constraint(lpIn, matrixSolve[matrixSolve.length - 1],
				constant.EQ, 1);

		// x1,y1

		resultInt = lpSolve.solve(lpIn);
		if (resultInt != constant.OPTIMAL) {
			mLog.logn("-- EQUATIONS ALGORITHM FAILED. NOT OPTIMAL");
			setSolved(false);
		} else {
			setSolved(true && isSolved());
		}

		k = 1;
		for (int i = 0; i < result.length; i++, k += 2) {
			result[i][1] = lpIn.getBestSolution(lpIn.getRows() + k)
					- lpIn.getBestSolution(lpIn.getRows() + k + 1);
		}

		V = lpIn.getBestSolution(lpIn.getRows() + k + 1)
				- lpIn.getBestSolution(lpIn.getRows() + k);

		// lpSolve.print_solution(lpIn);

		// double[][] rezultsX= temp.getMatrix();

		// result= new double[matrixU.length][2];
		mLog.logn("-- GENERATING OUTPUT");
		for (int i = 0; i < result.length; i++) {
			if (result[i][0] < 0 || result[i][1] < 0) {
				mLog.logn("-- EQUATION ALGORITHM FAILED");
				setSolved(false);
				break;
			}
		}

		mLog.logn("EQUATIONS U= " + U);
		mLog.logn("EQUATIONS V= " + V);

		mLog.logn("SOLVING EQUATIONS ENDS");
		mLog.logn("----------------------------------");
		// solveTMP(true);
                
	}

	/*
	 * public void solveTMP(boolean calculteUV) {
	 * mLog.logn("----------------------------------"); mLog.logn("SOLVING
	 * EQUATIONS BEGINS"); if(calculteUV) { mLog.logn("-- MATRIX U");
	 * calculateMatrixU(); mLog.logn("-- MATRIX V"); calculateMatrixV(); }
	 * 
	 * 
	 * 
	 * mLog.logn("-- SOLVING X"); int rows= 2; int cols= matrixU.length+2;
	 * double[][] matrixSolve= new double[rows][cols];
	 * 
	 * for(int i= 1; i<rows-1;i++) {
	 * 
	 * for(int j= 1; j< cols-1;j++) { double sum= 0; for(int k= 0; k<
	 * matrixU.length; k++) { sum+= matrixU[k][i-1]; } matrixSolve[i][j]= sum; }
	 * matrixSolve[i][cols-1]= -1; }
	 * 
	 * for(int j= 1; j< cols-1;j++ ) { matrixSolve[rows-1][j]= 1; }
	 * matrixSolve[rows-1][cols-1]= 0;
	 * 
	 * //create solve lpSolve = new solve(); lprec lpIn = new lprec(0,cols-1);
	 * 
	 * double[] bvalue= new double[cols]; Arrays.fill(bvalue, 0);
	 * 
	 * 
	 * bvalue[cols-1]= 1; //bvalue[cols-2]= -1; //bvalue[1]= 1;
	 * 
	 * //max lpSolve.set_obj_fn(lpIn,bvalue); lpSolve.set_maxim(lpIn);
	 * 
	 * //x-y for(int i = 1; i < rows-1; i++)
	 * lpSolve.add_constraint(lpIn,matrixSolve[i],constant.EQ,0);
	 * 
	 * lpSolve.add_constraint(lpIn,matrixSolve[matrixSolve.length-1],constant.EQ,1);
	 * 
	 * //x1,y1
	 * 
	 * int resultInt = lpSolve.solve(lpIn); if(resultInt != constant.OPTIMAL) {
	 * mLog.logn("-- EQUATIONS ALGORITHM FAILED"); setSolved(false); //return
	 * res; } else { setSolved(true); }
	 * 
	 * 
	 * result= new double[matrixU.length][2];
	 * 
	 * for(int i = 0; i < result.length; i++) { result[i][0]=
	 * lpIn.getBestSolution(lpIn.getRows()+i+1); }
	 * 
	 * U= lpIn.getBestSolution(lpIn.getRows()+result.length+1);
	 * 
	 * //lpSolve.print_solution(lpIn);
	 * 
	 * //double[][] rezultsY= lpSolve.getMatrix();
	 * 
	 * 
	 * mLog.logn("-- SOLVING Y"); matrixSolve= new double[rows][cols]; for(int
	 * i= 1; i<rows-1;i++) { double sum= 0; for(int k= 0; k< matrixV.length;
	 * k++) { sum+= matrixV[i-1][k]; } for(int j= 1; j< cols-1;j++) {
	 * matrixSolve[i][j]= sum; } matrixSolve[i][cols-1]= -1; }
	 * 
	 * for(int j= 1; j<= cols-1;j++) { matrixSolve[rows-1][j]= 1; }
	 * matrixSolve[rows-1][cols-1]= 0;
	 * 
	 * lpSolve = new solve(); lpIn = new lprec(0,cols-1);
	 * 
	 * //bvalue= new double[cols]; //Arrays.fill(bvalue, 0);
	 * 
	 * //max lpSolve.set_obj_fn(lpIn,bvalue); lpSolve.set_maxim(lpIn);
	 * 
	 * //x-y for(int i = 0; i < rows-1; i++)
	 * lpSolve.add_constraint(lpIn,matrixSolve[i],constant.EQ,0);
	 * 
	 * lpSolve.add_constraint(lpIn,matrixSolve[matrixSolve.length-1],constant.EQ,1);
	 * 
	 * //x1,y1
	 * 
	 * resultInt = lpSolve.solve(lpIn); if(resultInt != constant.OPTIMAL) {
	 * mLog.logn("-- EQUATIONS ALGORITHM FAILED. NOT OPTIMAL");
	 * setSolved(false); } else { setSolved(true&&isSolved()); }
	 * 
	 * for(int i = 0; i < result.length; i++) { result[i][1]=
	 * lpIn.getBestSolution(lpIn.getRows()+i+1); }
	 * 
	 * V= lpIn.getBestSolution(lpIn.getRows()+result.length+1);
	 * 
	 * //lpSolve.print_solution(lpIn);
	 * 
	 * //double[][] rezultsX= temp.getMatrix();
	 * 
	 * //result= new double[matrixU.length][2]; mLog.logn("-- GENERATING
	 * OUTPUT"); for(int i= 0;i<result.length;i++) { if(result[i][0] <0 ||
	 * result[i][1] <0) { mLog.logn("-- EQUATION ALGORITHM FAILED");
	 * setSolved(false); break; } }
	 * 
	 * mLog.logn("EQUATIONS U= "+U); mLog.logn("EQUATIONS V= "+V);
	 * 
	 * mLog.logn("SOLVING EQUATIONS ENDS");
	 * mLog.logn("----------------------------------"); //solveTMP(true); }
	 */

        
}
