#include<iostream>
#include"ilcplex/ilocplex.h";

using namespace std;


int main() {
	
	IloEnv env;
	try {
		IloModel model(env);

		ifstream data("tp.txt");
		//Ucitavamo podatke iz datoteke
		IloInt n, m, check;
		data >> m;
		data >> n;

		IloNumArray s(env, m);
		for (int j = 0; j < m; j++)
		{
			data >> s[j];
		}
		IloNumArray d(env, n);
		for (int i = 0; i < n; i++)
		{
			data >> d[i];
		}

		IloArray<IloNumArray> c(env, m);

		for (int i = 0; i < m; i++)
		{
			c[i] = IloNumArray(env, n);
			for (int j = 0; j < n; j++)
			{
				data >> c[i][j];
			}
		}
		data >> check;
		if (!check == 777)
			cout << "Podaci nisu dobro ucitani.";

		//definisemo promenljive
		//x_{ij}-matrica
		IloArray<IloNumVarArray> x(env, m);
		for (int i = 0; i < m; i++)
		{
			x[i] = IloNumVarArray(env, n, 0, INFINITY, ILOFLOAT);
		}
		//definisemo f-ju cilja
		IloExpr fc(env);
		for (int i = 0; i < m; i++)
		{

			for (int j = 0; j < n; j++)
			{
				fc += c[i][j] * x[i][j];
			}

		}
		model.add(IloMinimize(env, fc));
		//definisemo ogranicenja : svaki korisnik dobija kolicinu robe koju je potrzivao
		for (int j = 0; j < n; j++)
		{
			IloExpr cond1(env);
			for (int i = 0; i < m; i++)
			{
				cond1 += x[i][j];
			}
			model.add(cond1 == d[j]);
			cond1.end();
		}
		//definisemo ogranicenja: kapaciteti skladista moraju biti ispostovani
		for (int i = 0; i < m; i++)
		{
			IloExpr cond2(env);
			for (int j = 0; j < n; j++)
			{
				cond2 += x[i][j];
			}
			model.add(cond2 == s[i]);
			cond2.end();
		}

		IloCplex cplex(model);
		cplex.setOut(env.getNullStream());

		if (!cplex.solve()) {
			cerr << "Nije moguce resiti.";
			throw(-1);
		}

		//Ispisujemo na standardni izlaz i u datoteku
		cout << "Vrednost f-je cilja: " << cplex.getObjValue() << endl;
		cout << "Status: " << cplex.getStatus() << endl;
		cout << "Vreme: " << cplex.getTime() << endl;

		ofstream izlaz("tp_izlaz.txt");

		izlaz << "Vrednost f-je cilja: " << cplex.getObjValue() << endl;
		izlaz << "Status: " << cplex.getStatus() << endl;
		izlaz << "Vreme: " << cplex.getTime() << endl;

		izlaz << "Resenje: " << endl;
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				izlaz << cplex.getValue(x[i][j]) << " ";
			}
			izlaz << endl;
		}



	}
	catch (IloException& ex) {
	
		cerr << "Cplex greska: " << ex;
	
	}

























}


