root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / locate / locateAllocateB / LocateAllocateBAlgorithm.java @ 59
History | View | Annotate | Download (21.3 KB)
1 |
package es.unex.sextante.locate.locateAllocateB; |
---|---|
2 |
|
3 |
import java.text.DecimalFormat; |
4 |
import java.util.ArrayList; |
5 |
|
6 |
import com.vividsolutions.jts.geom.Coordinate; |
7 |
import com.vividsolutions.jts.geom.GeometryFactory; |
8 |
import com.vividsolutions.jts.geom.LineString; |
9 |
|
10 |
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue; |
11 |
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
12 |
import es.unex.sextante.core.GeoAlgorithm; |
13 |
import es.unex.sextante.core.Sextante; |
14 |
import es.unex.sextante.dataObjects.IFeature; |
15 |
import es.unex.sextante.dataObjects.IFeatureIterator; |
16 |
import es.unex.sextante.dataObjects.IRecord; |
17 |
import es.unex.sextante.dataObjects.IRecordsetIterator; |
18 |
import es.unex.sextante.dataObjects.ITable; |
19 |
import es.unex.sextante.dataObjects.IVectorLayer; |
20 |
import es.unex.sextante.docEngines.html.HTMLDoc; |
21 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
22 |
import es.unex.sextante.exceptions.OptionalParentParameterException; |
23 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
24 |
import es.unex.sextante.exceptions.UndefinedParentParameterNameException; |
25 |
import es.unex.sextante.math.simpleStats.SimpleStats; |
26 |
import es.unex.sextante.outputs.OutputVectorLayer; |
27 |
|
28 |
public class LocateAllocateBAlgorithm |
29 |
extends
|
30 |
GeoAlgorithm { |
31 |
|
32 |
public static final int EUCLIDEAN = 0; |
33 |
|
34 |
public static final int MINSUM = 0; |
35 |
public static final int CONSTRAINEDMINSUM = 1; |
36 |
public static final int MINSTDDEV = 2; |
37 |
public static final int MINIMAX = 3; |
38 |
public static final int MAXCOV = 4; |
39 |
public static final int MAXSUM = 5; |
40 |
public static final int MINCOV = 6; |
41 |
|
42 |
public static final String MAXDIST = "MAXDIST"; |
43 |
public static final String METHOD = "METHOD"; |
44 |
public static final String NEWLOCATIONS = "NEWLOCATIONS"; |
45 |
public static final String CANDIDATES = "CANDIDATES"; |
46 |
public static final String OFFER = "OFFER"; |
47 |
public static final String FIELDDEMAND = "FIELDDEMAND"; |
48 |
public static final String DEMAND = "DEMAND"; |
49 |
public static final String DEMAND_OFFER_DISTANCE_TABLE = "DEMAND_OFFER_DISTANCE_TABLE"; |
50 |
public static final String DEMAND_CANDIDATES_DISTANCE_TABLE = "DEMAND_CANDIDATES_DISTANCE_TABLE"; |
51 |
public static final String SPIDER = "SPIDER"; |
52 |
public static final String RESULT = "RESULT"; |
53 |
|
54 |
private static final int ITERATIONS = 100; |
55 |
|
56 |
private ArrayList m_Demand; |
57 |
private ArrayList m_Candidates; |
58 |
private ArrayList m_Offer; |
59 |
private double m_dDist[][]; |
60 |
private double m_dMaxDist; |
61 |
private double m_dObjective; |
62 |
private double m_dBestObjective; |
63 |
private int m_iNewLocations; |
64 |
private int[] m_iSolution; |
65 |
private int[] m_iBestSolution; |
66 |
private int m_iOffer; |
67 |
private int m_iTotalOffer; |
68 |
private int m_iMethod; |
69 |
private int m_iDemandField; |
70 |
private IVectorLayer m_DemandLayer;
|
71 |
private IVectorLayer m_OfferLayer;
|
72 |
private IVectorLayer m_CandidatesLayer;
|
73 |
private ITable m_DemandOfferDistanceTable;
|
74 |
private ITable m_DemandCandidatesDistanceTable;
|
75 |
|
76 |
|
77 |
@Override
|
78 |
public void defineCharacteristics() { |
79 |
|
80 |
final String sMethod[] = { Sextante.getText("Minimum_sum"), Sextante.getText("Minimum_sum_with_restrictions"), |
81 |
Sextante.getText("Minimum_standard_deviation"), Sextante.getText("Minimize_maximum_distance"), |
82 |
Sextante.getText("Maximum_coverage"), Sextante.getText("Maximum_sum"), Sextante.getText("Minimum_coverage") }; |
83 |
|
84 |
setName(Sextante.getText("Location-allocation_table_distance"));
|
85 |
setGroup(Sextante.getText("Location-allocation"));
|
86 |
setUserCanDefineAnalysisExtent(false);
|
87 |
setIsDeterminatedProcess(false);
|
88 |
try {
|
89 |
m_Parameters.addInputVectorLayer(DEMAND, Sextante.getText("Demand_points"), AdditionalInfoVectorLayer.SHAPE_TYPE_POINT,
|
90 |
true);
|
91 |
m_Parameters.addTableField(FIELDDEMAND, Sextante.getText("Field"), DEMAND);
|
92 |
m_Parameters.addInputVectorLayer(OFFER, Sextante.getText("Preexistent_resources"),
|
93 |
AdditionalInfoVectorLayer.SHAPE_TYPE_POINT, false);
|
94 |
m_Parameters.addInputVectorLayer(CANDIDATES, Sextante.getText("Candidate_points"),
|
95 |
AdditionalInfoVectorLayer.SHAPE_TYPE_POINT, true);
|
96 |
m_Parameters.addInputTable(DEMAND_OFFER_DISTANCE_TABLE, Sextante.getText("Demand_offer_distance_table"), true); |
97 |
m_Parameters.addInputTable(DEMAND_CANDIDATES_DISTANCE_TABLE, Sextante.getText("Demand_candidates_distance_table"), true); |
98 |
m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
|
99 |
m_Parameters.addNumericalValue(NEWLOCATIONS, Sextante.getText("Number_of_resources_to_allocate"),
|
100 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 1, 1, Integer.MAX_VALUE); |
101 |
m_Parameters.addNumericalValue(MAXDIST, Sextante.getText("Maximum_distance"),
|
102 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 1, 0, Double.MAX_VALUE); |
103 |
addOutputVectorLayer(SPIDER, Sextante.getText("Connections"), OutputVectorLayer.SHAPE_TYPE_LINE);
|
104 |
addOutputText(RESULT, Sextante.getText("Statistics"));
|
105 |
} |
106 |
catch (final RepeatedParameterNameException e) { |
107 |
Sextante.addErrorToLog(e); |
108 |
} |
109 |
catch (final UndefinedParentParameterNameException e) { |
110 |
Sextante.addErrorToLog(e); |
111 |
} |
112 |
catch (final OptionalParentParameterException e) { |
113 |
Sextante.addErrorToLog(e); |
114 |
} |
115 |
|
116 |
} |
117 |
|
118 |
|
119 |
@Override
|
120 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
121 |
|
122 |
m_DemandCandidatesDistanceTable = m_Parameters.getParameterValueAsTable(DEMAND_CANDIDATES_DISTANCE_TABLE); |
123 |
m_DemandOfferDistanceTable = m_Parameters.getParameterValueAsTable(DEMAND_OFFER_DISTANCE_TABLE); |
124 |
m_DemandLayer = m_Parameters.getParameterValueAsVectorLayer(DEMAND); |
125 |
m_iDemandField = m_Parameters.getParameterValueAsInt(FIELDDEMAND); |
126 |
m_OfferLayer = m_Parameters.getParameterValueAsVectorLayer(OFFER); |
127 |
m_CandidatesLayer = m_Parameters.getParameterValueAsVectorLayer(CANDIDATES); |
128 |
m_iNewLocations = m_Parameters.getParameterValueAsInt(NEWLOCATIONS); |
129 |
m_iMethod = m_Parameters.getParameterValueAsInt(METHOD); |
130 |
m_dMaxDist = m_Parameters.getParameterValueAsDouble(MAXDIST); |
131 |
|
132 |
if (m_iNewLocations == 0) { |
133 |
return false; |
134 |
} |
135 |
|
136 |
extractPoints(); |
137 |
calculateDistanceMatrix(); |
138 |
|
139 |
m_dBestObjective = Double.MAX_VALUE;
|
140 |
for (int i = 0; (i < ITERATIONS) && setProgress(i, ITERATIONS); i++) { |
141 |
setProgressText(Sextante.getText("Iteration") + " " + Integer.toString(i) + "/" + Integer.toString(ITERATIONS)); |
142 |
runTeitzBart(); |
143 |
if (m_dObjective < m_dBestObjective) {
|
144 |
m_dBestObjective = m_dObjective; |
145 |
m_iBestSolution = m_iSolution; |
146 |
} |
147 |
} |
148 |
|
149 |
if (m_Task.isCanceled()) {
|
150 |
return false; |
151 |
} |
152 |
else {
|
153 |
if (m_iBestSolution != null) { |
154 |
createResults(); |
155 |
} |
156 |
return true; |
157 |
} |
158 |
|
159 |
} |
160 |
|
161 |
|
162 |
private void extractPoints() throws GeoAlgorithmExecutionException { |
163 |
|
164 |
double dWeight;
|
165 |
|
166 |
m_Demand = new ArrayList(); |
167 |
m_Offer = new ArrayList(); |
168 |
m_Candidates = new ArrayList(); |
169 |
|
170 |
IFeatureIterator iter = m_DemandLayer.iterator(); |
171 |
while (iter.hasNext()) {
|
172 |
final IFeature feature = iter.next();
|
173 |
final Coordinate coord = feature.getGeometry().getCoordinate();
|
174 |
try {
|
175 |
dWeight = Double.parseDouble(feature.getRecord().getValue(m_iDemandField).toString());
|
176 |
} |
177 |
catch (final Exception e) { |
178 |
dWeight = 1;
|
179 |
} |
180 |
m_Demand.add(new DemandPoint(coord.x, coord.y, dWeight));
|
181 |
} |
182 |
iter.close(); |
183 |
|
184 |
iter = m_CandidatesLayer.iterator(); |
185 |
while (iter.hasNext()) {
|
186 |
final IFeature feature = iter.next();
|
187 |
final Coordinate coord = feature.getGeometry().getCoordinate();
|
188 |
m_Candidates.add(coord); |
189 |
} |
190 |
iter.close(); |
191 |
|
192 |
if (m_OfferLayer != null) { |
193 |
iter = m_OfferLayer.iterator(); |
194 |
while (iter.hasNext()) {
|
195 |
final IFeature feature = iter.next();
|
196 |
final Coordinate coord = feature.getGeometry().getCoordinate();
|
197 |
m_Offer.add(coord); |
198 |
} |
199 |
iter.close(); |
200 |
} |
201 |
|
202 |
if ((m_Candidates.size() < m_iNewLocations) || (m_Demand.size() == 0)) { |
203 |
throw new GeoAlgorithmExecutionException(Sextante.getText("Invalid_or_insufficient_data")); |
204 |
} |
205 |
|
206 |
} |
207 |
|
208 |
|
209 |
private void calculateDistanceMatrix() throws GeoAlgorithmExecutionException { |
210 |
|
211 |
m_iOffer = m_Offer.size(); |
212 |
m_iTotalOffer = m_Offer.size() + m_Candidates.size(); |
213 |
|
214 |
m_dDist = new double[m_Demand.size()][m_iTotalOffer]; |
215 |
|
216 |
IRecordsetIterator iter = m_DemandOfferDistanceTable.iterator(); |
217 |
int iDemand = 0; |
218 |
while (iter.hasNext()) {
|
219 |
final IRecord record = iter.next();
|
220 |
for (int j = 0; j < m_iOffer; j++) { |
221 |
final String sValue = record.getValue(j).toString(); |
222 |
try {
|
223 |
m_dDist[iDemand][j] = Double.parseDouble(sValue);
|
224 |
} |
225 |
catch (final Exception e) { |
226 |
throw new GeoAlgorithmExecutionException(Sextante.getText("Wrong_data_in_table")); |
227 |
} |
228 |
iDemand++; |
229 |
} |
230 |
} |
231 |
iter.close(); |
232 |
|
233 |
iter = m_DemandCandidatesDistanceTable.iterator(); |
234 |
iDemand = 0;
|
235 |
while (iter.hasNext()) {
|
236 |
final IRecord record = iter.next();
|
237 |
for (int j = 0; j < m_Candidates.size(); j++) { |
238 |
final String sValue = record.getValue(j).toString(); |
239 |
try {
|
240 |
m_dDist[iDemand][j + m_iOffer] = Double.parseDouble(sValue);
|
241 |
} |
242 |
catch (final Exception e) { |
243 |
throw new GeoAlgorithmExecutionException(Sextante.getText("Wrong_data_in_table")); |
244 |
} |
245 |
iDemand++; |
246 |
} |
247 |
} |
248 |
iter.close(); |
249 |
|
250 |
} |
251 |
|
252 |
|
253 |
private void runTeitzBart() { |
254 |
|
255 |
int i, j;
|
256 |
int iAlternative = 0; |
257 |
int iOldValue;
|
258 |
int iValueToChange = 0; |
259 |
int iRandCount, iCount;
|
260 |
double dMin;
|
261 |
boolean bHasImproved;
|
262 |
boolean bIsSelected;
|
263 |
m_iSolution = new int[m_iNewLocations]; |
264 |
|
265 |
for (i = 0; i < m_iSolution.length; i++) { |
266 |
m_iSolution[i] = i; |
267 |
} |
268 |
|
269 |
do {
|
270 |
bHasImproved = false;
|
271 |
dMin = getObjectiveFunctionValue(); |
272 |
iCount = 0;
|
273 |
iRandCount = (int) Math.floor(Math.random() * (m_Candidates.size() - m_iSolution.length)); |
274 |
for (i = 0; i < m_Candidates.size(); i++) { |
275 |
bIsSelected = false;
|
276 |
for (j = 0; j < m_iSolution.length; j++) { |
277 |
if (m_iSolution[j] == i) {
|
278 |
bIsSelected = true;
|
279 |
break;
|
280 |
} |
281 |
} |
282 |
if (!bIsSelected) {
|
283 |
if (iRandCount == iCount) {
|
284 |
iAlternative = i; |
285 |
break;
|
286 |
} |
287 |
else {
|
288 |
iCount++; |
289 |
} |
290 |
} |
291 |
} |
292 |
for (i = 0; i < m_iSolution.length; i++) { |
293 |
iOldValue = m_iSolution[i]; |
294 |
m_iSolution[i] = iAlternative; |
295 |
m_dObjective = getObjectiveFunctionValue(); |
296 |
if (m_dObjective < dMin) {
|
297 |
bHasImproved = true;
|
298 |
dMin = m_dObjective; |
299 |
iValueToChange = i; |
300 |
} |
301 |
m_iSolution[i] = iOldValue; |
302 |
} |
303 |
if (bHasImproved) {
|
304 |
m_iSolution[iValueToChange] = iAlternative; |
305 |
} |
306 |
} |
307 |
while (bHasImproved);
|
308 |
|
309 |
} |
310 |
|
311 |
|
312 |
private double getObjectiveFunctionValue() { |
313 |
|
314 |
switch (m_iMethod) {
|
315 |
case MINSUM:
|
316 |
default:
|
317 |
return getObjectiveFunctionValueMinSum();
|
318 |
case CONSTRAINEDMINSUM:
|
319 |
return getObjectiveFunctionValueConstrainedMinSum();
|
320 |
case MINSTDDEV:
|
321 |
return getObjectiveFunctionValueMinStdDev();
|
322 |
case MAXSUM:
|
323 |
return -getObjectiveFunctionValueMinSum();
|
324 |
case MAXCOV:
|
325 |
return getObjectiveFunctionValueMaxCov();
|
326 |
case MINCOV:
|
327 |
return -getObjectiveFunctionValueMaxCov();
|
328 |
case MINIMAX:
|
329 |
return getObjectiveFunctionValueMinMaxDistance();
|
330 |
} |
331 |
|
332 |
} |
333 |
|
334 |
|
335 |
private double getObjectiveFunctionValueMinStdDev() { |
336 |
|
337 |
int i, j;
|
338 |
int iPt;
|
339 |
double dMin;
|
340 |
double dSum = 0; |
341 |
double dVar = 0; |
342 |
|
343 |
|
344 |
for (i = 0; i < m_Demand.size(); i++) { |
345 |
dMin = Double.MAX_VALUE;
|
346 |
for (j = 0; j < m_iOffer; j++) { |
347 |
if (m_dDist[i][j] < dMin) {
|
348 |
dMin = m_dDist[i][j]; |
349 |
} |
350 |
} |
351 |
for (j = 0; j < m_iSolution.length; j++) { |
352 |
iPt = m_iSolution[j]; |
353 |
if (m_dDist[i][iPt + m_iOffer] < dMin) {
|
354 |
dMin = m_dDist[i][iPt + m_iOffer]; |
355 |
} |
356 |
} |
357 |
//TODO dpt = (DemandPoint) m_Demand.get(i); �NO CONSIDERAMOS PESOS????
|
358 |
|
359 |
dSum += dMin; |
360 |
dVar += dMin * dMin; |
361 |
|
362 |
} |
363 |
|
364 |
dSum /= m_Demand.size(); |
365 |
dVar = dVar / m_Demand.size() - dSum * dSum; |
366 |
|
367 |
return dVar;
|
368 |
|
369 |
} |
370 |
|
371 |
|
372 |
private double getObjectiveFunctionValueConstrainedMinSum() { |
373 |
|
374 |
int i, j;
|
375 |
int iPt;
|
376 |
double dValue = 0; |
377 |
double dMin;
|
378 |
DemandPoint dpt; |
379 |
|
380 |
for (i = 0; i < m_Demand.size(); i++) { |
381 |
dMin = Double.MAX_VALUE;
|
382 |
for (j = 0; j < m_iOffer; j++) { |
383 |
if (m_dDist[i][j] < dMin) {
|
384 |
dMin = m_dDist[i][j]; |
385 |
} |
386 |
} |
387 |
for (j = 0; j < m_iSolution.length; j++) { |
388 |
iPt = m_iSolution[j]; |
389 |
if (m_dDist[i][iPt + m_iOffer] < dMin) {
|
390 |
dMin = m_dDist[i][iPt + m_iOffer]; |
391 |
} |
392 |
} |
393 |
if (dMin < m_dMaxDist) {
|
394 |
dpt = (DemandPoint) m_Demand.get(i); |
395 |
dValue += (dMin * dpt.weight); |
396 |
} |
397 |
else {
|
398 |
dValue = Double.POSITIVE_INFINITY;
|
399 |
} |
400 |
|
401 |
} |
402 |
|
403 |
return dValue;
|
404 |
|
405 |
} |
406 |
|
407 |
|
408 |
private double getObjectiveFunctionValueMaxCov() { |
409 |
|
410 |
int i, j;
|
411 |
int iPt;
|
412 |
double dValue = 0; |
413 |
double dDemand;;
|
414 |
DemandPoint dpt; |
415 |
|
416 |
for (i = 0; i < m_Demand.size(); i++) { |
417 |
dpt = (DemandPoint) m_Demand.get(i); |
418 |
dDemand = dpt.weight; |
419 |
for (j = 0; j < m_iOffer; j++) { |
420 |
if (m_dDist[i][j] < m_dMaxDist) {
|
421 |
dDemand = 0;
|
422 |
break;
|
423 |
} |
424 |
} |
425 |
if (dDemand != 0) { |
426 |
for (j = 0; j < m_iSolution.length; j++) { |
427 |
iPt = m_iSolution[j]; |
428 |
if (m_dDist[i][iPt + m_iOffer] < m_dMaxDist) {
|
429 |
dDemand = 0;
|
430 |
break;
|
431 |
} |
432 |
} |
433 |
} |
434 |
|
435 |
dValue += dDemand; |
436 |
} |
437 |
|
438 |
return dValue;
|
439 |
|
440 |
} |
441 |
|
442 |
|
443 |
private double getObjectiveFunctionValueMinSum() { |
444 |
|
445 |
int i, j;
|
446 |
int iPt;
|
447 |
double dValue = 0; |
448 |
double dMin;
|
449 |
DemandPoint dpt; |
450 |
|
451 |
for (i = 0; i < m_Demand.size(); i++) { |
452 |
dMin = Double.MAX_VALUE;
|
453 |
for (j = 0; j < m_iOffer; j++) { |
454 |
if (m_dDist[i][j] < dMin) {
|
455 |
dMin = m_dDist[i][j]; |
456 |
} |
457 |
} |
458 |
for (j = 0; j < m_iSolution.length; j++) { |
459 |
iPt = m_iSolution[j]; |
460 |
if (m_dDist[i][iPt + m_iOffer] < dMin) {
|
461 |
dMin = m_dDist[i][iPt + m_iOffer]; |
462 |
} |
463 |
} |
464 |
dpt = (DemandPoint) m_Demand.get(i); |
465 |
dValue += (dMin * dpt.weight); |
466 |
} |
467 |
|
468 |
return dValue;
|
469 |
|
470 |
} |
471 |
|
472 |
|
473 |
private double getObjectiveFunctionValueMinMaxDistance() { |
474 |
|
475 |
int i, j;
|
476 |
int iPt;
|
477 |
double dMin, dMax = Double.NEGATIVE_INFINITY; |
478 |
|
479 |
for (i = 0; i < m_Demand.size(); i++) { |
480 |
dMin = Double.MAX_VALUE;
|
481 |
for (j = 0; j < m_iOffer; j++) { |
482 |
if (m_dDist[i][j] < dMin) {
|
483 |
dMin = m_dDist[i][j]; |
484 |
} |
485 |
} |
486 |
for (j = 0; j < m_iSolution.length; j++) { |
487 |
iPt = m_iSolution[j]; |
488 |
if (m_dDist[i][iPt + m_iOffer] < dMin) {
|
489 |
dMin = m_dDist[i][iPt + m_iOffer]; |
490 |
} |
491 |
} |
492 |
if (dMax < dMin) {
|
493 |
dMax = dMin; |
494 |
} |
495 |
} |
496 |
|
497 |
return dMax;
|
498 |
|
499 |
} |
500 |
|
501 |
|
502 |
private void createResults() throws GeoAlgorithmExecutionException { |
503 |
|
504 |
int i, j;
|
505 |
int iPt;
|
506 |
int iID = 1; |
507 |
double dMin;
|
508 |
double dDist;
|
509 |
DemandPoint dpt; |
510 |
Coordinate pt = null;
|
511 |
LineString line; |
512 |
final Coordinate coords[] = new Coordinate[2]; |
513 |
final Object values[] = new Object[8]; |
514 |
String sOfferName = null; |
515 |
final String[] sNames = { Sextante.getText("ID"), Sextante.getText("Demand_point"), Sextante.getText("X_demand"), |
516 |
Sextante.getText("Y_demand"), Sextante.getText("Resource"), Sextante.getText("X_resource"), |
517 |
Sextante.getText("Y_resource"), Sextante.getText("Distance") }; |
518 |
final Class[] types = { Integer.class, String.class, Double.class, Double.class, String.class, Double.class, Double.class, |
519 |
Double.class };
|
520 |
final SimpleStats stats = new SimpleStats(); |
521 |
final IVectorLayer spiderWebLayer = getNewVectorLayer(SPIDER, Sextante.getText("Conexions"), IVectorLayer.SHAPE_TYPE_LINE, |
522 |
types, sNames); |
523 |
final IVectorLayer newPointsLayer = getNewVectorLayer(RESULT, Sextante.getText("Selected_points"), |
524 |
IVectorLayer.SHAPE_TYPE_POINT, new Class[] { Integer.class }, new String[] { "ID" }); |
525 |
|
526 |
final GeometryFactory gf = new GeometryFactory(); |
527 |
|
528 |
for (i = 0; i < m_iBestSolution.length; i++) { |
529 |
iPt = m_iBestSolution[i]; |
530 |
pt = (Coordinate) m_Candidates.get(iPt); |
531 |
newPointsLayer.addFeature(gf.createPoint(pt), new Object[] { new Integer(i) }); |
532 |
} |
533 |
|
534 |
|
535 |
for (i = 0; i < m_Demand.size(); i++) { |
536 |
dpt = (DemandPoint) m_Demand.get(i); |
537 |
dMin = Double.MAX_VALUE;
|
538 |
for (j = 0; j < m_iOffer; j++) { |
539 |
if (m_dDist[i][j] < dMin) {
|
540 |
dMin = m_dDist[i][j]; |
541 |
pt = (Coordinate) m_Offer.get(j); |
542 |
sOfferName = Sextante.getText("Preexistent") + Integer.toString(j); |
543 |
} |
544 |
} |
545 |
for (j = 0; j < m_iBestSolution.length; j++) { |
546 |
iPt = m_iBestSolution[j]; |
547 |
if (m_dDist[i][iPt + m_iOffer] < dMin) {
|
548 |
dMin = m_dDist[i][iPt + m_iOffer]; |
549 |
pt = (Coordinate) m_Candidates.get(iPt); |
550 |
sOfferName = Sextante.getText("Candidate") + Integer.toString(iPt); |
551 |
} |
552 |
} |
553 |
|
554 |
stats.addValue(dMin); |
555 |
coords[0] = pt;
|
556 |
coords[1] = new Coordinate(dpt.x, dpt.y); |
557 |
line = gf.createLineString(coords); |
558 |
values[0] = new Integer(iID++); |
559 |
values[1] = Integer.toString(i); |
560 |
values[2] = new Double(dpt.x); |
561 |
values[3] = new Double(dpt.y); |
562 |
values[4] = sOfferName;
|
563 |
values[5] = new Double(pt.x); |
564 |
values[6] = new Double(pt.y); |
565 |
dDist = Math.sqrt(Math.pow(pt.x - dpt.x, 2) + Math.pow(pt.y - dpt.y, 2)); |
566 |
values[7] = new Double(dDist); |
567 |
spiderWebLayer.addFeature(line, values); |
568 |
|
569 |
} |
570 |
|
571 |
final DecimalFormat df = new DecimalFormat("##.###"); |
572 |
final HTMLDoc doc = new HTMLDoc(); |
573 |
doc.open(Sextante.getText("Result"));
|
574 |
doc.addHeader(Sextante.getText("Statistics_of_global_solution"), 2); |
575 |
doc.startUnorderedList(); |
576 |
doc.addListElement(Sextante.getText("Objective_function") + ": " + df.format(Math.abs(m_dObjective))); |
577 |
doc.addListElement(Sextante.getText("Mean_distance") + ": " + df.format(stats.getMean())); |
578 |
doc.addListElement(Sextante.getText("Mean_squared_distance") + ": " + df.format(stats.getRMS())); |
579 |
doc.addListElement(Sextante.getText("Min_distance") + ": " + df.format(stats.getMin())); |
580 |
doc.addListElement(Sextante.getText("Maximum_distance") + ": " + df.format(stats.getMax())); |
581 |
doc.addListElement(Sextante.getText("Variance") + ": " + df.format(stats.getVariance())); |
582 |
doc.addListElement(Sextante.getText("Sum_of_distances") + ": " + df.format(stats.getSum())); |
583 |
doc.addListElement(Sextante.getText("Coefficient_of_variation") + ": " + df.format(stats.getCoeffOfVar())); |
584 |
doc.closeUnorderedList(); |
585 |
doc.close(); |
586 |
|
587 |
addOutputText(RESULT, Sextante.getText("Statistics"), doc.getHTMLCode());
|
588 |
|
589 |
} |
590 |
|
591 |
private class DemandPoint { |
592 |
|
593 |
public double x; |
594 |
public double y; |
595 |
public double weight; |
596 |
|
597 |
|
598 |
DemandPoint(final double dX, |
599 |
final double dY, |
600 |
final double dWeight) { |
601 |
|
602 |
x = dX; |
603 |
y = dY; |
604 |
weight = dWeight; |
605 |
|
606 |
} |
607 |
} |
608 |
} |