1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#include "LPSolveClass.hpp"
#include "lp_lib.h"
#include <algorithm>

namespace MeshKit
{
//---------------------------------------------------------------------------//
// construction function for LPSolveClass class
LPSolveClass::LPSolveClass()<--- Member variable 'LPSolveClass::obj_const' is not initialized in the constructor.
{
	

}



//---------------------------------------------------------------------------//
// deconstruction function for LPSolveClass class
LPSolveClass::~LPSolveClass()
{

}

//setup the objective function  : cx
void LPSolveClass::SetupObj(vector<double> left, double const_value)
{
	obj_const = const_value;
	coefficients.resize(left.size());
	for (unsigned int i = 0; i < left.size(); i++)
		coefficients[i] = left[i];
}

//setup the equal constraints   : Ax = b
void LPSolveClass::SetupEqu(vector<vector<double> > left, vector<double> right){

	assert(left.size()==right.size());
	A_equ.resize(left.size());
	b_equ.resize(right.size());
	for (unsigned int i = 0; i < left.size(); i++){
		A_equ[i].resize(left[i].size());
		b_equ[i] = right[i];
		for (unsigned int j = 0; j < left[i].size(); j++)
			A_equ[i][j] = left[i][j];
	}
}

//setup the inequal constraints: always, Ax <= b
void LPSolveClass::SetupInEqu(vector<vector<double> > left, vector<double> right){

	assert(left.size()==right.size());
	A_inequ.resize(left.size());
	b_inequ.resize(right.size());
	for (unsigned int i = 0; i < left.size(); i++){
		A_inequ[i].resize(left[i].size());
		b_inequ[i] = right[i];
		for (unsigned int j = 0; j < left[i].size(); j++)
			A_inequ[i][j] = left[i][j];
	}
}
//setup the const constraint
void LPSolveClass::SetupConst(vector<int> right)
{
	b_const.resize(right.size());
	for (unsigned int i = 0; i < right.size(); i++)
		b_const[i] =right[i];
}

//Execute function
int LPSolveClass::Execute()
{
	/*
	std::cout << "---------------------------------\n";
	std::cout << "objective function\n";
	for (unsigned int i = 0; i < coefficients.size(); i++)
		std::cout << coefficients[i] << "\t";
	std::cout << "\nConstant Value = " << obj_const << std::endl;

	std::cout << "---------------------------------\n";
	std::cout << "Equality Constraints\n";	
	for (unsigned int i = 0; i < A_equ.size(); i++){
		//std::cout << "Row index = " << i << "\t\t";
		for (unsigned int j = 0; j < A_equ[i].size(); j++)
			std::cout << A_equ[i][j] << "\t";
		std::cout << "\n";
	}
	std::cout << "b\n";
	for (unsigned int i = 0; i < b_equ.size(); i++)
		std::cout << b_equ[i] << "\t";
	std::cout << "\n";


	std::cout << "---------------------------------\n";
	std::cout << "InEquality Constraints\n";	
	for (unsigned int i = 0; i < A_inequ.size(); i++){
		//std::cout << "Row index = " << i << "\t\t";
		for (unsigned int j = 0; j < A_inequ[i].size(); j++)
			std::cout << A_inequ[i][j] << "\t";
		std::cout << "\n";
	}
	std::cout << "b\n";
	for (unsigned int i = 0; i < b_inequ.size(); i++)
		std::cout << b_inequ[i] << "\t";
	std::cout << "\n";
	*/

	lprec *lp;
	int Ncol = coefficients.size(), *colno = NULL, j, ret = 0;<--- The scope of the variable 'j' can be reduced.
	REAL *row = NULL;
	
	/* We will build the model row by row
     So we start with creating a model with 0 rows and n columns */

	lp = make_lp(0, Ncol);
	if (lp == NULL)
		ret = 1;/* couldn't construct a new model... */
		
	if (ret == 0){
		//let us name our variables
		std::string s = "x";
		for (int i = 0; i < Ncol; i++){
			std::stringstream out;
			out << i;
			s = s + out.str();
			char *cpy = new char[s.size()+1] ;
			strcpy(cpy, s.c_str());			
			set_col_name(lp, i+1, cpy);
		}

		/* create space large enough for one row */
		colno = (int *) malloc(Ncol * sizeof(*colno));
    	row = (REAL *) malloc(Ncol * sizeof(*row));
		if ((colno == NULL) || (row == NULL))
      		ret = 2;
	}

	set_add_rowmode(lp, TRUE);
	//add the equation constraints
	if (ret == 0){
		/* makes building the model faster if it is done rows by row */
		if (A_equ.size() > 0){
			for (unsigned int i = 0; i < A_equ.size(); i++){//loop over the rows of equality constraints
				for (unsigned int j = 0; j < A_equ[i].size(); j++){//loop over the columns of equality constraints
					colno[j] = j+1;//add the j-th column to lpsolve
					row[j] = A_equ[i][j];
				}
				/* add the row to lpsolve */
				if(!add_constraintex(lp, A_equ[i].size(), row, colno, EQ, b_equ[i]))
					ret = 2;
			}
		}
	}
	
	//add the inequality constraints
	if (ret == 0){
		/* makes building the model faster if it is done rows by row */
		if (A_inequ.size() > 0){
			for (unsigned int i = 0; i < A_inequ.size(); i++){//loop over the rows of inequality constraints
				for (unsigned int j = 0; j < A_inequ[i].size(); j++){//loop over the columns of inequality constraints
					colno[j] = j+1;//add the j-th column to lpsolve
					row[j] = A_inequ[i][j];
				}
				/* add the row to lpsolve */
				if(!add_constraintex(lp, A_inequ[i].size(), row, colno, LE, b_inequ[i]))
					ret = 3;
			}
		}
	}

	//add the const constraint	
	if (ret == 0){
		if (b_const.size()>0){
			for (unsigned int i = 0; i < b_const.size(); i++){
				if (b_const[i] > 0){
					for (unsigned int j = 0; j < b_const.size(); j++){
						if (i == j){
							colno[j] = j+1;//add the j-th column to lpsolve
							row[j] = 1.0;						
						}				
						else{
							colno[j] = j+1;//add the j-th column to lpsolve
							row[j] = 0.0;
						}
					}
					if(!add_constraintex(lp, b_const.size(), row, colno, EQ, b_const[i]))
						ret = 4;		
				}
			}
		}
	}

	//set the variables to be integer
	if (ret == 0){
		for (int i = 0; i < Ncol; i++)
			set_int(lp, i+1, TRUE);
	}
	
	/* rowmode should be turned off again when done building the model */
	set_add_rowmode(lp, FALSE);	
	//add the objective function
	if (ret == 0){
		//set the objective function
		for (unsigned int i = 0; i < coefficients.size(); i++){
			colno[i] = i+1;
			row[i] = coefficients[i];
		}
		//set the objective in lpsolve
		if(!set_obj_fnex(lp, coefficients.size(), row, colno))
      		ret = 4;
	}

	//set the objective to minimize
	if (ret == 0){
		set_minim(lp);

		/* just out of curioucity, now show the model in lp format on screen */
    	/* this only works if this is a console application. If not, use write_lp and a filename */
    	write_LP(lp, stdout);

		/* I only want to see important messages on screen while solving */
    	set_verbose(lp, IMPORTANT);

    	/* Now let lpsolve calculate a solution */
    	ret = solve(lp);
    	if(ret == OPTIMAL)
      		ret = 0;
    	else
      		ret = 5;
	}

	//get some results
	if (ret == 0){
		/* a solution is calculated, now lets get some results */

    	/* objective value */
    	std::cout << "Objective value: " << get_objective(lp) << std::endl;

		/* variable values */
    	get_variables(lp, row);

		/* variable values */
		variables.resize(Ncol);
		for(j = 0; j < Ncol; j++)
			variables[j] = row[j];

		/* we are done now */
	}
	else{
		std::cout << "The optimal value can't be solved for linear programming, please check the constraints!!\n";
		exit(1);

	}
		
	
	std::cout << "print the result\t # of line segments is \n";
	for (int i = 0; i < Ncol; i++)
		std::cout << "index = " << i << "\t# = " << variables[i] << std::endl;

	/* free allocated memory */
  	if(row != NULL)
    	free(row);
  	if(colno != NULL)
    	free(colno);

	/* clean up such that all used memory by lpsolve is freed */
	if (lp != NULL)
		delete_lp(lp);

	return ret;
}

void LPSolveClass::GetVariables(vector<int> &var){
	var.resize(variables.size());
	for(unsigned int i = 0; i < variables.size(); i++)
		var[i] = variables[i];

}

}