#include<ilcplex/ilocplex.h>

ILOSTLBEGIN

//********************TP********************
int main(int, char**) {
	IloEnv env;
	try {
		IloModel model(env);
		//citamo podatke (m i n)
		IloInt m, n, check;

		ifstream data("ulaz_TP.txt");
		data >> m;
		data >> n;

		//definisemo parametre
		IloArray<IloNumArray> C(env, m);
		for (int i = 0; i < m; i++)
			C[i] = IloNumArray(env, n);

		IloNumArray O(env, m);
		IloNumArray D(env, n);

		//citamo podatke

		for (int i = 0; i < m; i++)
			data >> O[i];

		for (int j = 0; j < n; j++)
			data >> D[j];

		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
				data >> C[i][j];


		data >> check;

		if (check == 777)
			cout << "Podaci su uspesno ucitani." << endl;
		else
			cout << "Greska pri ucitavanju podataka." << endl;

		//definisemo promenljive
		IloArray<IloNumVarArray> x(env, m);
		for (int i = 0; i < m; i++) {
			x[i] = IloNumVarArray(env, n, 0, IloInfinity);
		}

		//Funkcija cilja
		IloExpr fo(env);
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
				fo += C[i][j] * x[i][j];

		model.add(IloMinimize(env, fo));

		//ogranicenja
		IloExpr Expr(env);

		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				Expr += x[i][j];
			}
			model.add(Expr == O[i]);
			Expr.end();
			Expr = IloExpr(env);
		}

		IloExpr Expr2(env);

		for (int j = 0; j < n; j++) {
			for (int i = 0; i < m; i++) {
				Expr2 += x[i][j];
			}
			model.add(Expr2 == D[j]);
			Expr2.end();
			Expr2 = IloExpr(env);
		}

		//odavde nadole standardno
		IloCplex cplex(env);
		cplex.setOut(env.getNullStream());
		cplex.extract(model);
		cplex.exportModel("model_TP.lp");

		if (!cplex.solve()) {
			env.error() << "Nije moguce resiti :-(" << endl;
			throw(-1);
		}

		//ispisi promenljive
		ofstream izlaz("izlazTP.txt");
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				izlaz << cplex.getValue(x[i][j]) << " ";
			}
			izlaz << endl;
		}
		env.out() << "Status: " << cplex.getStatus() << endl;
		env.out() << "Vrednost funkcije cilja: " << cplex.getObjValue() << endl;
		env.out() << "Vreme izvrsavanja: " << cplex.getTime() << endl;
	} catch (IloException& ex){
		cerr << "Error Cplex: " << ex << endl;
	}
}





