1 | /* |
---|
2 | Copyright (C) 2012 |
---|
3 | Alejandro Mujica (amujica@cenditel.gob.ve) |
---|
4 | José Ruiz (jruiz@cenditel.gob.ve) |
---|
5 | Julie Vera (jvera@cenditel.gob.ve) |
---|
6 | |
---|
7 | CENDITEL Fundación Centro Nacional de Desarrollo e Investigación en |
---|
8 | Tecnologías Libres |
---|
9 | |
---|
10 | Este programa es software libre; Usted puede usarlo bajo los términos de la |
---|
11 | licencia de software GPL versión 2.0 de la Free Software Foundation. |
---|
12 | |
---|
13 | Este programa se distribuye con la esperanza de que sea útil, pero SIN |
---|
14 | NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o |
---|
15 | ADECUACIÓN A UN PROPÓSITO PARTICULAR. |
---|
16 | Consulte la licencia GPL para más detalles. Usted debe recibir una copia |
---|
17 | de la GPL junto con este programa; si no, escriba a la Free Software |
---|
18 | Foundation Inc. 51 Franklin Street,5 Piso, Boston, MA 02110-1301, USA. |
---|
19 | */ |
---|
20 | |
---|
21 | /* |
---|
22 | Autor: Alejandro J. Mujica |
---|
23 | Fecha de creación: 05/06/2014 |
---|
24 | Este archivo contiene la definición de la clase IO_Manager. |
---|
25 | */ |
---|
26 | |
---|
27 | # ifndef IO_MANAGER_H |
---|
28 | # define IO_MANAGER_H |
---|
29 | |
---|
30 | # include <tpl_graph_indexes.H> |
---|
31 | |
---|
32 | # include <product.H> |
---|
33 | # include <input.H> |
---|
34 | # include <imported_product.H> |
---|
35 | # include <ip_relationship.H> |
---|
36 | # include <exogenous_variables.H> |
---|
37 | # include <queries.H> |
---|
38 | # include <utils.H> |
---|
39 | |
---|
40 | typedef Graph_Node<std::shared_ptr<Good>> Node; |
---|
41 | |
---|
42 | typedef Graph_Arc<IP_Relationship> Arc; |
---|
43 | |
---|
44 | typedef List_Graph <Node, Arc> Graph; |
---|
45 | |
---|
46 | /** Clase de operaciones que contiene operaciones de Entrada-Salida para |
---|
47 | * un grafo que representa redes productivas sobre archivos. |
---|
48 | * |
---|
49 | * Construye un grafo de la información de base de datos a partir del archivo |
---|
50 | * xml con las raíces, añade un grafo a un archivo xml, lee un grafo de un xml, |
---|
51 | * lee los valores de simulación de un xml y añade valores de simulación a un |
---|
52 | * xml. |
---|
53 | * |
---|
54 | * @author Alejandro J. Mujica |
---|
55 | */ |
---|
56 | class IO_Manager { |
---|
57 | |
---|
58 | public: |
---|
59 | |
---|
60 | static const std::string ZERO; |
---|
61 | |
---|
62 | static const std::string ONE; |
---|
63 | |
---|
64 | static const std::string UTF_8; |
---|
65 | |
---|
66 | static const std::string VALUE; |
---|
67 | |
---|
68 | static const std::string PRODUCTION; |
---|
69 | |
---|
70 | static const std::string ATTRIBUTES; |
---|
71 | |
---|
72 | static const std::string YEAR; |
---|
73 | |
---|
74 | static const std::string ROOT_NODE; |
---|
75 | |
---|
76 | static const std::string CODE; |
---|
77 | |
---|
78 | static const std::string RANKS; |
---|
79 | |
---|
80 | static const std::string UP; |
---|
81 | |
---|
82 | static const std::string DOWN; |
---|
83 | |
---|
84 | static const std::string COPYRIGHT; |
---|
85 | |
---|
86 | static const std::string XML_GRAPH; |
---|
87 | |
---|
88 | static const std::string XML_NODES; |
---|
89 | |
---|
90 | static const std::string XML_NODE; |
---|
91 | |
---|
92 | static const std::string XML_ARCS; |
---|
93 | |
---|
94 | static const std::string XML_ARC; |
---|
95 | |
---|
96 | static const std::string XML_SIMULATION; |
---|
97 | |
---|
98 | static const std::string XML_SIMULATED_GRAPH; |
---|
99 | |
---|
100 | static const std::string XML_SIMULATED_NODES; |
---|
101 | |
---|
102 | static const std::string XML_SIMULATED_NODE; |
---|
103 | |
---|
104 | static const std::string XML_SIMULATED_ARCS; |
---|
105 | |
---|
106 | static const std::string XML_SIMULATED_ARC; |
---|
107 | |
---|
108 | static const std::string XML_SIMULATED_STATES; |
---|
109 | |
---|
110 | static const std::string XML_SIMULATED_STATE; |
---|
111 | |
---|
112 | static const std::string XML_STATE_NUMBER; |
---|
113 | |
---|
114 | static const std::string XML_STOCK; |
---|
115 | |
---|
116 | static const std::string XML_INTERNAL_REQUESTED_QUANTITY; |
---|
117 | |
---|
118 | static const std::string XML_EXTERNAL_REQUESTED_QUANTITY; |
---|
119 | |
---|
120 | static const std::string XML_TOTAL_REQUESTED_QUANTITY; |
---|
121 | |
---|
122 | static const std::string XML_DAILY_WAGE; |
---|
123 | |
---|
124 | static const std::string XML_OTHER_WAGE; |
---|
125 | |
---|
126 | static const std::string XML_OTHER_DAILY_WAGE; |
---|
127 | |
---|
128 | static const std::string XML_DAILY_FEEDING_COUPON; |
---|
129 | |
---|
130 | static const std::string XML_FEEDING_COUPON; |
---|
131 | |
---|
132 | static const std::string XML_INTEGRAL_WAGE; |
---|
133 | |
---|
134 | static const std::string XML_ADMINISTRATIVE_STAFF_COST; |
---|
135 | |
---|
136 | static const std::string XML_LABOR_COST; |
---|
137 | |
---|
138 | static const std::string XML_INPUT_COST; |
---|
139 | |
---|
140 | static const std::string XML_OTHER_COST; |
---|
141 | |
---|
142 | static const std::string XML_TOTAL_COST; |
---|
143 | |
---|
144 | static const std::string XML_UNITARIAN_ADMINISTRATIVE_STAFF_COST; |
---|
145 | |
---|
146 | static const std::string XML_UNITARIAN_LABOR_COST; |
---|
147 | |
---|
148 | static const std::string XML_INPUT_COST_PER_UNIT; |
---|
149 | |
---|
150 | static const std::string XML_OTHER_UNITARIAN_COST; |
---|
151 | |
---|
152 | static const std::string XML_INCOME; |
---|
153 | |
---|
154 | static const std::string XML_ECONOMIC_STATUS; |
---|
155 | |
---|
156 | static const std::string XML_OPTION; |
---|
157 | |
---|
158 | static const std::string XML_VARIATION; |
---|
159 | |
---|
160 | static const std::string XML_POSITION; |
---|
161 | |
---|
162 | static const std::string XML_LEVEL; |
---|
163 | |
---|
164 | static const std::string XML_COMPANY_NAME; |
---|
165 | |
---|
166 | static const std::string XML_COMPANY_RIF; |
---|
167 | |
---|
168 | static const std::string XML_COMPANY_LOCATION; |
---|
169 | |
---|
170 | static const std::string XML_COMPANY_NATIONALITY; |
---|
171 | |
---|
172 | static const std::string XML_PRODUCT_ID; |
---|
173 | |
---|
174 | static const std::string XML_PRODUCT_NAME; |
---|
175 | |
---|
176 | static const std::string XML_TARIFF_CODE; |
---|
177 | |
---|
178 | static const std::string XML_MEASUREMENT_UNIT; |
---|
179 | |
---|
180 | static const std::string XML_QUANTITY; |
---|
181 | |
---|
182 | static const std::string XML_REQ_QUANTITY; |
---|
183 | |
---|
184 | static const std::string XML_BOUGHT_QUANTITY; |
---|
185 | |
---|
186 | static const std::string XML_UNITARIAN_PRICE; |
---|
187 | |
---|
188 | static const std::string XML_TYPE; |
---|
189 | |
---|
190 | static const std::string XML_SRC; |
---|
191 | |
---|
192 | static const std::string XML_TGT; |
---|
193 | |
---|
194 | static const std::string XML_INPUT_ID; |
---|
195 | |
---|
196 | static const std::string XML_PURCHASE_PRICE; |
---|
197 | |
---|
198 | static const std::string XML_PRODUCTION_CAPACITY; |
---|
199 | |
---|
200 | static const std::string XML_PRODUCTION; |
---|
201 | |
---|
202 | static const std::string XML_INTERNAL_SALES; |
---|
203 | |
---|
204 | static const std::string XML_EXTERNAL_SALES; |
---|
205 | |
---|
206 | static const std::string XML_WORKDAY; |
---|
207 | |
---|
208 | static const std::string XML_NUM_ADMINISTRATIVE_STAFF; |
---|
209 | |
---|
210 | static const std::string XML_NUM_EMPLOYEES; |
---|
211 | |
---|
212 | static const std::string XML_PRICE; |
---|
213 | |
---|
214 | static const std::string XML_IMPORTS; |
---|
215 | |
---|
216 | static const std::string XML_SALE; |
---|
217 | |
---|
218 | static const std::string XML_REQUESTED_QUANTITY; |
---|
219 | |
---|
220 | static const std::string XML_EXOGENOUS_VARIABLES; |
---|
221 | |
---|
222 | static const std::string XML_AVERAGE_SALARY; |
---|
223 | |
---|
224 | static const std::string XML_RATE_OF_CHANGE_OF_SALARY; |
---|
225 | |
---|
226 | static const std::string XML_RATE_OF_GAIN; |
---|
227 | |
---|
228 | static const std::string XML_RATE_OF_PRICE_CHANGE; |
---|
229 | |
---|
230 | static const std::string XML_RATE_OF_CHANGE_IN_FINAL_DEMAND; |
---|
231 | |
---|
232 | static const std::string XML_NOMINAL_EXCHANGE_RATE; |
---|
233 | |
---|
234 | static const std::string XML_UT; |
---|
235 | |
---|
236 | static const std::string XML_SIGMA; |
---|
237 | |
---|
238 | static const std::string XML_NUM_IT; |
---|
239 | |
---|
240 | /** Busca en un árbol xml un nodo con el nombre dado |
---|
241 | * |
---|
242 | * @param root puntero a la raiz del árbol. |
---|
243 | * @param name nombre del nodo que se quiere buscar. |
---|
244 | * @return Puntero al nodo con el nombre dado o NULL si no existe. |
---|
245 | */ |
---|
246 | xmlpp::Element * search_xml_element_by_name(xmlpp::Element * root, |
---|
247 | const std::string & name) |
---|
248 | { |
---|
249 | if (root->get_name() == name) |
---|
250 | return root; |
---|
251 | |
---|
252 | DynListQueue<xmlpp::Element *> queue; |
---|
253 | |
---|
254 | queue.put(root); |
---|
255 | |
---|
256 | while (not queue.is_empty()) |
---|
257 | { |
---|
258 | xmlpp::Node * node = queue.get(); |
---|
259 | |
---|
260 | xmlpp::Node::NodeList children = node->get_children(); |
---|
261 | |
---|
262 | for (xmlpp::Node::NodeList::iterator it = children.begin(); |
---|
263 | it != children.end(); ++it) |
---|
264 | { |
---|
265 | |
---|
266 | xmlpp::Node * child = *it; |
---|
267 | |
---|
268 | if (child->get_name() == name) |
---|
269 | return static_cast <xmlpp::Element *>(child); |
---|
270 | |
---|
271 | queue.put(static_cast <xmlpp::Element *>(child)); |
---|
272 | } |
---|
273 | } |
---|
274 | |
---|
275 | return NULL; |
---|
276 | } |
---|
277 | |
---|
278 | /** Lee el archivo xml y extrae el código del producto raíz. |
---|
279 | * |
---|
280 | * @param[in] file_name Nombre del archivo xml. |
---|
281 | * @param[out] root_id Id del producto raíz. |
---|
282 | * @param[out] levels_upstream Cantidad máxima de niveles hacia arriba. |
---|
283 | * @param[out] levels_downstream Cantidad máxima de niveles hacia abajo. |
---|
284 | * @param[out] year Año de estudio de la red. |
---|
285 | * @throw logic_error si algún nodo no tiene atributos. |
---|
286 | */ |
---|
287 | void read_fields(const std::string & file_name, std::string & year, |
---|
288 | db_id_t & root_id, |
---|
289 | size_t & levels_upstream, size_t & levels_downstream) |
---|
290 | { |
---|
291 | |
---|
292 | xmlpp::TextReader reader(file_name); |
---|
293 | |
---|
294 | while(reader.read()) |
---|
295 | { |
---|
296 | if (reader.get_name() == ROOT_NODE) |
---|
297 | { |
---|
298 | if (not reader.has_attributes()) |
---|
299 | throw std::logic_error("root has not attributes"); |
---|
300 | |
---|
301 | reader.move_to_first_attribute(); |
---|
302 | root_id = std::atol(reader.get_value().c_str()); |
---|
303 | reader.move_to_element(); |
---|
304 | |
---|
305 | } |
---|
306 | else if (reader.get_name() == RANKS) |
---|
307 | { |
---|
308 | if (not reader.has_attributes()) |
---|
309 | throw std::logic_error("var ranks has not attributes"); |
---|
310 | |
---|
311 | reader.move_to_first_attribute(); |
---|
312 | levels_upstream = std::atol(reader.get_value().c_str()); |
---|
313 | reader.move_to_next_attribute(); |
---|
314 | levels_downstream = std::atol(reader.get_value().c_str()); |
---|
315 | reader.move_to_element(); |
---|
316 | } |
---|
317 | else if (reader.get_name() == YEAR) |
---|
318 | { |
---|
319 | if (not reader.has_attributes()) |
---|
320 | throw std::logic_error("var year has not attributes"); |
---|
321 | |
---|
322 | reader.move_to_first_attribute(); |
---|
323 | year = reader.get_value().c_str(); |
---|
324 | reader.move_to_element(); |
---|
325 | } |
---|
326 | } |
---|
327 | } |
---|
328 | |
---|
329 | /** Crea un archivo XML con los parámetros para construir una red productiva. |
---|
330 | * |
---|
331 | * @param year_value Año de estudio de la red productiva. |
---|
332 | * @param id Id del producto que será raíz. |
---|
333 | * @param levels_upstream Número máximo de niveles hacia arriba. |
---|
334 | * @param levels_downstream Número máximo de niveles hacia abajo. |
---|
335 | * @param output_file_name Nombre del archivo sobre el cual se escribirán |
---|
336 | * los datos. |
---|
337 | */ |
---|
338 | void create_xml_root_file(const std::string & year_value, |
---|
339 | const db_id_t & root_id, |
---|
340 | const size_t & levels_upstream, |
---|
341 | const size_t & levels_downstream, |
---|
342 | const std::string & output_file_name) |
---|
343 | { |
---|
344 | xmlpp::Document doc; |
---|
345 | |
---|
346 | xmlpp::Element * production = doc.create_root_node(PRODUCTION); |
---|
347 | |
---|
348 | xmlpp::Element * attributes = production->add_child(ATTRIBUTES); |
---|
349 | |
---|
350 | xmlpp::Element * year = attributes->add_child(YEAR); |
---|
351 | |
---|
352 | year->set_attribute(VALUE, year_value); |
---|
353 | |
---|
354 | xmlpp::Element * root = attributes->add_child(ROOT_NODE); |
---|
355 | |
---|
356 | std::stringstream str_code; |
---|
357 | |
---|
358 | str_code << root_id; |
---|
359 | |
---|
360 | root->set_attribute(CODE, str_code.str()); |
---|
361 | |
---|
362 | xmlpp::Element * ranks = attributes->add_child(RANKS); |
---|
363 | |
---|
364 | std::stringstream up_value; |
---|
365 | |
---|
366 | up_value << levels_upstream; |
---|
367 | |
---|
368 | ranks->set_attribute(UP, up_value.str()); |
---|
369 | |
---|
370 | std::stringstream down_value; |
---|
371 | |
---|
372 | down_value << levels_downstream; |
---|
373 | |
---|
374 | ranks->set_attribute(DOWN, down_value.str()); |
---|
375 | |
---|
376 | doc.write_to_file_formatted(output_file_name, UTF_8); |
---|
377 | } |
---|
378 | |
---|
379 | void set_product_info(Product * ptr_product, const std::string & year) |
---|
380 | { |
---|
381 | Aleph::pair<real, real> production_and_price = |
---|
382 | get_produced_quantity_and_price(ptr_product->get_id(), year); |
---|
383 | |
---|
384 | ptr_product->set_production(production_and_price.first); |
---|
385 | |
---|
386 | ptr_product->set_price(production_and_price.second); |
---|
387 | |
---|
388 | real used_capacity = get_product_used_capacity(ptr_product->get_id(), year); |
---|
389 | |
---|
390 | real max_capacity = used_capacity == 0.0 ? ptr_product->get_production() : |
---|
391 | ptr_product->get_production() * 100.0 / used_capacity; |
---|
392 | |
---|
393 | ptr_product->set_production_capacity(max_capacity); |
---|
394 | |
---|
395 | std::tuple<real, real, real> staff_info = |
---|
396 | get_product_staff_numbers(ptr_product->get_company_rif(), year, |
---|
397 | ptr_product->get_id()); |
---|
398 | |
---|
399 | ptr_product->set_workday(std::get<0>(staff_info)); |
---|
400 | ptr_product->set_num_administrative_staff( |
---|
401 | std::ceil(std::get<1>(staff_info)) |
---|
402 | ); |
---|
403 | ptr_product->set_num_employees(std::ceil(std::get<2>(staff_info))); |
---|
404 | } |
---|
405 | |
---|
406 | /** Construye la red productiva hacia aguas arriba a partir de las raíces. |
---|
407 | * |
---|
408 | * @param g Grafo sobre el cual se va a construir la red. |
---|
409 | * @param queue cola en la que se encuentran las raices para efectual el |
---|
410 | * recorrido en amplitud. |
---|
411 | */ |
---|
412 | void build_graph_upstream(Graph & g, Graph::Node * start_node, |
---|
413 | const size_t & max_levels_upstream, |
---|
414 | const std::string & year) |
---|
415 | { |
---|
416 | Map<std::string, Graph::Node *> input_map; |
---|
417 | |
---|
418 | Map<long, Graph::Node *> product_map; |
---|
419 | |
---|
420 | Queue<Graph::Node *> queue; |
---|
421 | |
---|
422 | queue.put(start_node); |
---|
423 | |
---|
424 | while (not queue.is_empty()) |
---|
425 | { |
---|
426 | Graph::Node * tgt = queue.get(); |
---|
427 | |
---|
428 | std::shared_ptr<Good> & good = tgt->get_info(); |
---|
429 | |
---|
430 | List<db_id_t> input_ids; |
---|
431 | |
---|
432 | list_input_ids(good->get_id(), year, input_ids); |
---|
433 | |
---|
434 | for (List<db_id_t>::Iterator iit(input_ids); iit.has_current(); |
---|
435 | iit.next()) |
---|
436 | { |
---|
437 | const db_id_t & input_id = iit.get_current(); |
---|
438 | |
---|
439 | List<Input> inputs; |
---|
440 | |
---|
441 | list_inputs(input_id, year, inputs); |
---|
442 | |
---|
443 | for (List<Input>::Iterator it(inputs); it.has_current(); |
---|
444 | it.next()) |
---|
445 | { |
---|
446 | Input & input = it.get_current(); |
---|
447 | |
---|
448 | List<Product> products; |
---|
449 | |
---|
450 | product_from_input(input, products); |
---|
451 | |
---|
452 | if (products.is_empty()) // Es un insumo (nacional o importado) |
---|
453 | { |
---|
454 | Graph::Node ** ptr_src = NULL; |
---|
455 | Graph::Node * src = NULL; |
---|
456 | |
---|
457 | std::stringstream scode; |
---|
458 | scode << input.get_id(); |
---|
459 | |
---|
460 | if (input.get_nationality() != "E") |
---|
461 | scode << input.get_company_rif(); |
---|
462 | else |
---|
463 | scode << input.get_company_name(); |
---|
464 | |
---|
465 | std::string code = scode.str(); |
---|
466 | |
---|
467 | ptr_src = input_map.search(code); |
---|
468 | |
---|
469 | if (ptr_src == NULL) // Hay que insertarlo en el grafo |
---|
470 | { |
---|
471 | std::shared_ptr<Good> ptr_good; |
---|
472 | |
---|
473 | if (input.get_nationality() != "E") |
---|
474 | ptr_good = std::shared_ptr<Good>(new Input(input)); |
---|
475 | else |
---|
476 | { |
---|
477 | std::unique_ptr<Imported_Product> |
---|
478 | ptr_imported_product(new Imported_Product); |
---|
479 | |
---|
480 | ptr_imported_product->set_company_rif( |
---|
481 | input.get_company_rif() |
---|
482 | ); |
---|
483 | ptr_imported_product->set_company_name( |
---|
484 | input.get_company_name() |
---|
485 | ); |
---|
486 | ptr_imported_product->set_company_location( |
---|
487 | input.get_company_location() |
---|
488 | ); |
---|
489 | ptr_imported_product->set_nationality( |
---|
490 | input.get_nationality() |
---|
491 | ); |
---|
492 | ptr_imported_product->set_id(input.get_id()); |
---|
493 | ptr_imported_product->set_name(input.get_name()); |
---|
494 | ptr_imported_product->set_tariff_code( |
---|
495 | input.get_tariff_code() |
---|
496 | ); |
---|
497 | ptr_imported_product->set_measurement_unit( |
---|
498 | input.get_measurement_unit() |
---|
499 | ); |
---|
500 | |
---|
501 | ptr_good = std::shared_ptr<Good>( |
---|
502 | ptr_imported_product.release() |
---|
503 | ); |
---|
504 | } |
---|
505 | src = g.insert_node(ptr_good); |
---|
506 | |
---|
507 | input_map.insert(code, src); |
---|
508 | } |
---|
509 | else |
---|
510 | src = *ptr_src; |
---|
511 | |
---|
512 | IP_Relationship ip_relationship; |
---|
513 | |
---|
514 | ip_relationship.set_input_id(input.get_id()); |
---|
515 | |
---|
516 | ip_relationship.set_requested_quantity( |
---|
517 | get_unitarian_request(input.get_id(), |
---|
518 | tgt->get_info()->get_id()) |
---|
519 | ); |
---|
520 | |
---|
521 | ip_relationship.set_purchase_price( |
---|
522 | get_acquisition_price(input.get_nationality(), |
---|
523 | input.get_id(), year) |
---|
524 | ); |
---|
525 | |
---|
526 | ip_relationship.set_bought_quantity( |
---|
527 | get_declared_bought_quantity( |
---|
528 | src->get_info()->get_company_rif(), |
---|
529 | src->get_info()->get_company_name(), |
---|
530 | input.get_id(), |
---|
531 | year |
---|
532 | ) |
---|
533 | ); |
---|
534 | |
---|
535 | if (input.get_nationality() != "E") |
---|
536 | { |
---|
537 | Imported_Product * ptr_imported_product = |
---|
538 | static_cast<Imported_Product *>( |
---|
539 | src->get_info().get()); |
---|
540 | |
---|
541 | ptr_imported_product->set_imports( |
---|
542 | ptr_imported_product->get_imports() + |
---|
543 | ip_relationship.get_bought_quantity() |
---|
544 | ); |
---|
545 | } |
---|
546 | |
---|
547 | src->get_info()->set_level( |
---|
548 | tgt->get_info()->get_level() - 1 |
---|
549 | ); |
---|
550 | |
---|
551 | g.insert_arc(src, tgt, ip_relationship); |
---|
552 | |
---|
553 | continue; // Paso al siguiente insumo |
---|
554 | } |
---|
555 | |
---|
556 | // Si llego a este punto es porque hay productos en la lista |
---|
557 | |
---|
558 | for (List <Product>::Iterator it(products); it.has_current(); |
---|
559 | it.next()) |
---|
560 | { |
---|
561 | Product & product = it.get_current(); |
---|
562 | |
---|
563 | Graph::Node ** ptr_src = NULL; |
---|
564 | Graph::Node * src = NULL; |
---|
565 | |
---|
566 | ptr_src = product_map.search(product.get_id()); |
---|
567 | |
---|
568 | if (ptr_src == NULL) |
---|
569 | { |
---|
570 | Product * ptr_product = new Product(product); |
---|
571 | |
---|
572 | std::shared_ptr<Good> ptr_good(ptr_product); |
---|
573 | |
---|
574 | set_product_info(ptr_product, year); |
---|
575 | |
---|
576 | src = g.insert_node(ptr_good); |
---|
577 | |
---|
578 | product_map.insert(product.get_id(), src); |
---|
579 | } |
---|
580 | else |
---|
581 | src = *ptr_src; |
---|
582 | |
---|
583 | Product * ptr_product = |
---|
584 | static_cast<Product *>(src->get_info().get()); |
---|
585 | |
---|
586 | IP_Relationship ip_relationship; |
---|
587 | |
---|
588 | ip_relationship.set_input_id(input.get_id()); |
---|
589 | |
---|
590 | ip_relationship.set_requested_quantity( |
---|
591 | get_unitarian_request(input.get_id(), |
---|
592 | tgt->get_info()->get_id()) |
---|
593 | ); |
---|
594 | |
---|
595 | if (ptr_product->get_price() == 0.0) |
---|
596 | get_acquisition_price(input.get_nationality(), |
---|
597 | input.get_id(), year); |
---|
598 | else |
---|
599 | ip_relationship.set_purchase_price( |
---|
600 | ptr_product->get_price() |
---|
601 | ); |
---|
602 | |
---|
603 | ip_relationship.set_bought_quantity( |
---|
604 | get_declared_bought_quantity( |
---|
605 | ptr_product->get_company_rif(), |
---|
606 | ptr_product->get_company_name(), |
---|
607 | input.get_id(), |
---|
608 | year |
---|
609 | ) |
---|
610 | ); |
---|
611 | |
---|
612 | src->get_info()->set_level( |
---|
613 | tgt->get_info()->get_level() - 1 |
---|
614 | ); |
---|
615 | |
---|
616 | g.insert_arc(src, tgt, ip_relationship); |
---|
617 | |
---|
618 | if (ptr_src == NULL and |
---|
619 | std::abs(src->get_info()->get_level()) < |
---|
620 | max_levels_upstream) |
---|
621 | queue.put(src); |
---|
622 | } |
---|
623 | } |
---|
624 | } |
---|
625 | } |
---|
626 | } |
---|
627 | |
---|
628 | /** Construye la red productiva hacia aguas abajo a partir de las raíces. |
---|
629 | * |
---|
630 | * @param g Grafo sobre el cual se va a construir la red. |
---|
631 | * @param queue cola en la que se encuentran las raices para efectual el |
---|
632 | * recorrido en amplitud. |
---|
633 | */ |
---|
634 | void build_graph_downstream(Graph & g, Graph::Node * start_node, |
---|
635 | const size_t & max_levels_downstream, |
---|
636 | const std::string & year) { |
---|
637 | |
---|
638 | Map<long, Graph::Node *> product_map; |
---|
639 | |
---|
640 | Queue<Graph::Node *> queue; |
---|
641 | |
---|
642 | queue.put(start_node); |
---|
643 | |
---|
644 | while (not queue.is_empty()) |
---|
645 | { |
---|
646 | Graph::Node * src = queue.get(); |
---|
647 | |
---|
648 | Good * good = src->get_info().get(); |
---|
649 | |
---|
650 | Product * ptr_product = static_cast<Product *>(good); |
---|
651 | |
---|
652 | List<Aleph::pair<Product, long>> requesters; |
---|
653 | |
---|
654 | list_requesters(good, requesters); |
---|
655 | |
---|
656 | for (List<Aleph::pair<Product, long>>::Iterator it(requesters); |
---|
657 | it.has_current(); it.next()) |
---|
658 | { |
---|
659 | Aleph::pair<Product, long> & current_pair = it.get_current(); |
---|
660 | |
---|
661 | Product & product = current_pair.first; |
---|
662 | |
---|
663 | product.set_level(src->get_info()->get_level() + 1); |
---|
664 | |
---|
665 | const db_id_t & input_id = current_pair.second; |
---|
666 | |
---|
667 | Graph::Node ** ptr_tgt = product_map.search(product.get_id()); |
---|
668 | |
---|
669 | Graph::Node * tgt; |
---|
670 | |
---|
671 | if (ptr_tgt == NULL) |
---|
672 | { |
---|
673 | set_product_info(&product, year); |
---|
674 | std::shared_ptr<Good> ptr_good(new Product(product)); |
---|
675 | tgt = g.insert_node(ptr_good); |
---|
676 | product_map.insert(product.get_id(), tgt); |
---|
677 | } |
---|
678 | else |
---|
679 | tgt = *ptr_tgt; |
---|
680 | |
---|
681 | IP_Relationship ip_relationship; |
---|
682 | |
---|
683 | ip_relationship.set_input_id(input_id); |
---|
684 | |
---|
685 | ip_relationship.set_requested_quantity( |
---|
686 | get_unitarian_request(input_id, tgt->get_info()->get_id()) |
---|
687 | ); |
---|
688 | |
---|
689 | ip_relationship.set_bought_quantity( |
---|
690 | get_declared_bought_quantity( |
---|
691 | ptr_product->get_company_rif(), |
---|
692 | ptr_product->get_company_name(), |
---|
693 | input_id, |
---|
694 | year |
---|
695 | ) |
---|
696 | ); |
---|
697 | |
---|
698 | ip_relationship.set_purchase_price(ptr_product->get_price()); |
---|
699 | |
---|
700 | g.insert_arc(src, tgt, ip_relationship); |
---|
701 | |
---|
702 | if (tgt->get_info()->get_level() < max_levels_downstream and |
---|
703 | ptr_tgt == NULL) |
---|
704 | queue.put(tgt); |
---|
705 | } |
---|
706 | } |
---|
707 | } |
---|
708 | |
---|
709 | void set_internal_and_external_sales(Graph & g, const std::string & year) |
---|
710 | { |
---|
711 | for (Graph::Node_Iterator it(g); it.has_current(); it.next()) |
---|
712 | { |
---|
713 | |
---|
714 | Graph::Node * node = it.get_current(); |
---|
715 | |
---|
716 | Good * ptr_good = node->get_info().get(); |
---|
717 | |
---|
718 | real internal_sales = 0.0; |
---|
719 | |
---|
720 | std::string buyer_rif_set; |
---|
721 | |
---|
722 | size_t num_buyers = 0; |
---|
723 | |
---|
724 | real accum_price = 0.0; |
---|
725 | |
---|
726 | for (Graph::Node_Arc_Iterator nait(node); nait.has_current(); |
---|
727 | nait.next()) |
---|
728 | { |
---|
729 | Graph::Arc * arc = nait.get_current(); |
---|
730 | |
---|
731 | if (g.get_tgt_node(arc) == node) |
---|
732 | continue; |
---|
733 | |
---|
734 | const IP_Relationship & ip_rel = arc->get_info(); |
---|
735 | |
---|
736 | internal_sales += ip_rel.get_purchase_price() * |
---|
737 | ip_rel.get_bought_quantity(); |
---|
738 | |
---|
739 | Graph::Node * buyer_node = g.get_tgt_node(arc); |
---|
740 | |
---|
741 | if (buyer_rif_set.size() > 0) |
---|
742 | buyer_rif_set.append(", "); |
---|
743 | |
---|
744 | buyer_rif_set.append( |
---|
745 | single_quote(buyer_node->get_info()->get_company_rif()) |
---|
746 | ); |
---|
747 | |
---|
748 | accum_price += ip_rel.get_purchase_price(); |
---|
749 | |
---|
750 | ++num_buyers; |
---|
751 | } |
---|
752 | |
---|
753 | real external_sales = 0.0; |
---|
754 | |
---|
755 | real avg_price = accum_price / num_buyers; |
---|
756 | |
---|
757 | switch (ptr_good->get_type()) |
---|
758 | { |
---|
759 | case PRODUCT: |
---|
760 | external_sales = get_external_sales(ptr_good->get_tariff_code(), |
---|
761 | ptr_good->get_company_rif(), |
---|
762 | year, buyer_rif_set); |
---|
763 | (static_cast<Product *>(ptr_good)) |
---|
764 | ->set_internal_sales(internal_sales); |
---|
765 | (static_cast<Product *>(ptr_good)) |
---|
766 | ->set_external_sales(external_sales); |
---|
767 | |
---|
768 | break; |
---|
769 | |
---|
770 | case INPUT: |
---|
771 | external_sales = get_external_sales(ptr_good->get_tariff_code(), |
---|
772 | ptr_good->get_company_rif(), |
---|
773 | year, buyer_rif_set); |
---|
774 | |
---|
775 | (static_cast<Input *>(ptr_good)) |
---|
776 | ->set_internal_sales(internal_sales); |
---|
777 | (static_cast<Input *>(ptr_good)) |
---|
778 | ->set_external_sales(external_sales); |
---|
779 | |
---|
780 | (static_cast<Input *>(ptr_good)) |
---|
781 | ->set_price(avg_price); |
---|
782 | |
---|
783 | break; |
---|
784 | |
---|
785 | case IMPORTED_PRODUCT: |
---|
786 | (static_cast<Imported_Product *>(ptr_good)) |
---|
787 | ->set_imports(internal_sales / avg_price); |
---|
788 | (static_cast<Imported_Product *>(ptr_good)) |
---|
789 | ->set_sale(internal_sales); |
---|
790 | (static_cast<Imported_Product *>(ptr_good)) |
---|
791 | ->set_requested_quantity(internal_sales / avg_price); |
---|
792 | (static_cast<Imported_Product *>(ptr_good)) |
---|
793 | ->set_price(avg_price); |
---|
794 | |
---|
795 | } |
---|
796 | } |
---|
797 | } |
---|
798 | |
---|
799 | /** Construye el grafo a partir de los valores dados en el archivo xml. |
---|
800 | * |
---|
801 | * @param file_name Nombre del archivo xml en el que se encuentra la |
---|
802 | * información relevante para la construcción de la red. |
---|
803 | * @param g Grafo sobre el cual se va a construir la red. |
---|
804 | */ |
---|
805 | void build_graph(const std::string & file_name, Graph & g) |
---|
806 | { |
---|
807 | db_id_t root_id; |
---|
808 | |
---|
809 | size_t levels_upstream; |
---|
810 | |
---|
811 | size_t levels_downstream; |
---|
812 | |
---|
813 | std::string year; |
---|
814 | |
---|
815 | read_fields(file_name, year, root_id, levels_upstream, levels_downstream); |
---|
816 | |
---|
817 | Product product = load_product_by_id(root_id); |
---|
818 | |
---|
819 | if (product.get_id() == 0) |
---|
820 | { |
---|
821 | std::stringstream msg; |
---|
822 | msg << "There is not product with id = " << root_id; |
---|
823 | throw std::domain_error(msg.str()); |
---|
824 | } |
---|
825 | |
---|
826 | set_product_info(&product, year); |
---|
827 | |
---|
828 | std::shared_ptr<Good> ptr_good(new Product(product)); |
---|
829 | |
---|
830 | Graph::Node * r = g.insert_node(ptr_good); |
---|
831 | |
---|
832 | if (levels_upstream > 0) |
---|
833 | build_graph_upstream(g, r, levels_upstream, year); |
---|
834 | |
---|
835 | if (levels_downstream > 0) |
---|
836 | build_graph_downstream(g, r, levels_downstream, year); |
---|
837 | |
---|
838 | set_internal_and_external_sales(g, year); |
---|
839 | } |
---|
840 | |
---|
841 | /** Llena un arreglo de nodos que contienen espacios en blando en un árbol |
---|
842 | * xml. |
---|
843 | * |
---|
844 | * @param root raíz del árbol xml. |
---|
845 | * @param blanks arreglo en el cual se almacenarán los nodos con espacios |
---|
846 | * en blanco. |
---|
847 | */ |
---|
848 | void remove_white_spaces(xmlpp::Node * root, |
---|
849 | Array<xmlpp::Node *> & blanks) { |
---|
850 | |
---|
851 | xmlpp::TextNode * node = dynamic_cast<xmlpp::TextNode *>(root); |
---|
852 | |
---|
853 | if (node and node->is_white_space()) |
---|
854 | blanks.append(node); |
---|
855 | |
---|
856 | xmlpp::Node::NodeList children = root->get_children(); |
---|
857 | |
---|
858 | for (xmlpp::Node::NodeList::iterator it = children.begin(); |
---|
859 | it != children.end(); ++it) |
---|
860 | remove_white_spaces(*it, blanks); |
---|
861 | } |
---|
862 | |
---|
863 | /** Elimina los nodos que contienen espacios en blanco de un nodo xml. |
---|
864 | * |
---|
865 | * @param raíz del árbol xml. |
---|
866 | */ |
---|
867 | void remove_white_spaces(xmlpp::Node * root) { |
---|
868 | |
---|
869 | Array<xmlpp::Node *> blanks; |
---|
870 | |
---|
871 | remove_white_spaces(root, blanks); |
---|
872 | |
---|
873 | for (size_t i = 0; i < blanks.size(); ++i) { |
---|
874 | |
---|
875 | xmlpp::Node * child = blanks.access(i); |
---|
876 | xmlpp::Node * parent = child->get_parent(); |
---|
877 | parent->remove_child(child); |
---|
878 | } |
---|
879 | } |
---|
880 | |
---|
881 | /** Añade la información de un grafo a un archivo xml. |
---|
882 | * |
---|
883 | * @param g grafo que se va a añadir al archivo. |
---|
884 | * @param input_file_name nombre del archivo donde hay información base para |
---|
885 | * el nuevo archivo. |
---|
886 | * @param output_file_name nombre del archivo en el cual se escribirá la |
---|
887 | * las información base extraída del archivo original más el grafo. |
---|
888 | */ |
---|
889 | void add_graph_to_xml(Graph & g, const std::string & input_file_name, |
---|
890 | const std::string & output_file_name) |
---|
891 | { |
---|
892 | xmlpp::DomParser parser; |
---|
893 | |
---|
894 | parser.parse_file(input_file_name); |
---|
895 | |
---|
896 | xmlpp::Document * doc = parser.get_document(); |
---|
897 | |
---|
898 | I(doc != NULL); |
---|
899 | |
---|
900 | xmlpp::Element * root = doc->get_root_node(); |
---|
901 | |
---|
902 | I(doc != NULL); |
---|
903 | |
---|
904 | remove_white_spaces(root); |
---|
905 | |
---|
906 | xmlpp::Element * graph = root->add_child(XML_GRAPH); |
---|
907 | |
---|
908 | xmlpp::Element * nodes = graph->add_child(XML_NODES); |
---|
909 | |
---|
910 | Map<Graph::Node *, size_t> node_map; |
---|
911 | |
---|
912 | size_t i = 0; // Contador de nodos |
---|
913 | |
---|
914 | for (Graph::Node_Iterator it(g); it.has_current(); it.next(), ++i) |
---|
915 | { |
---|
916 | Graph::Node * current_node = it.get_current(); |
---|
917 | |
---|
918 | node_map.insert(current_node, i); |
---|
919 | |
---|
920 | Good * good = current_node->get_info().get(); |
---|
921 | |
---|
922 | xmlpp::Element * node = nodes->add_child(XML_NODE); |
---|
923 | |
---|
924 | node->set_attribute(XML_POSITION, num_to_str(i)); |
---|
925 | node->set_attribute(XML_LEVEL, num_to_str(good->get_level())); |
---|
926 | |
---|
927 | node->set_attribute(XML_COMPANY_RIF, good->get_company_rif()); |
---|
928 | node->set_attribute(XML_COMPANY_NAME, good->get_company_name()); |
---|
929 | node->set_attribute(XML_COMPANY_LOCATION, good->get_company_location()); |
---|
930 | node->set_attribute(XML_COMPANY_NATIONALITY, good->get_nationality()); |
---|
931 | |
---|
932 | node->set_attribute(XML_PRODUCT_ID, num_to_str(good->get_id())); |
---|
933 | node->set_attribute(XML_PRODUCT_NAME, good->get_name()); |
---|
934 | node->set_attribute(XML_TARIFF_CODE, good->get_tariff_code()); |
---|
935 | node->set_attribute(XML_MEASUREMENT_UNIT, |
---|
936 | good->get_measurement_unit()); |
---|
937 | |
---|
938 | Good_Type type = good->get_type(); |
---|
939 | |
---|
940 | node->set_attribute(XML_TYPE, num_to_str(int(type))); |
---|
941 | |
---|
942 | switch (type) |
---|
943 | { |
---|
944 | case PRODUCT: |
---|
945 | { |
---|
946 | Product * product = static_cast<Product *>(good); |
---|
947 | |
---|
948 | node->set_attribute(XML_PRODUCTION_CAPACITY, |
---|
949 | num_to_str( |
---|
950 | product->get_production_capacity())); |
---|
951 | node->set_attribute(XML_PRODUCTION, |
---|
952 | num_to_str(product->get_production())); |
---|
953 | node->set_attribute(XML_INTERNAL_SALES, |
---|
954 | num_to_str(product->get_internal_sales())); |
---|
955 | node->set_attribute(XML_EXTERNAL_SALES, |
---|
956 | num_to_str(product->get_external_sales())); |
---|
957 | node->set_attribute(XML_WORKDAY, |
---|
958 | num_to_str(product->get_workday())); |
---|
959 | node->set_attribute(XML_NUM_ADMINISTRATIVE_STAFF, |
---|
960 | num_to_str(product->get_num_administrative_staff())); |
---|
961 | node->set_attribute(XML_NUM_EMPLOYEES, |
---|
962 | num_to_str(product->get_num_employees())); |
---|
963 | node->set_attribute(XML_PRICE, num_to_str(product->get_price())); |
---|
964 | node->set_attribute(XML_OTHER_COST, |
---|
965 | num_to_str(product->get_other_cost())); |
---|
966 | } |
---|
967 | |
---|
968 | break; |
---|
969 | case INPUT: |
---|
970 | { |
---|
971 | Input * input = static_cast<Input *>(good); |
---|
972 | |
---|
973 | real production = (input->get_internal_sales() + |
---|
974 | input->get_external_sales()) / |
---|
975 | input->get_price(); |
---|
976 | |
---|
977 | node->set_attribute(XML_PRODUCTION, num_to_str(production)); |
---|
978 | node->set_attribute(XML_INTERNAL_SALES, |
---|
979 | num_to_str(input->get_internal_sales())); |
---|
980 | node->set_attribute(XML_EXTERNAL_SALES, |
---|
981 | num_to_str(input->get_external_sales())); |
---|
982 | node->set_attribute(XML_PRICE, num_to_str(input->get_price())); |
---|
983 | } |
---|
984 | |
---|
985 | break; |
---|
986 | case IMPORTED_PRODUCT: |
---|
987 | { |
---|
988 | Imported_Product * imported_product = |
---|
989 | static_cast<Imported_Product *>(good); |
---|
990 | |
---|
991 | node->set_attribute(XML_IMPORTS, |
---|
992 | num_to_str(imported_product->get_imports())); |
---|
993 | node->set_attribute(XML_SALE, |
---|
994 | num_to_str(imported_product->get_sale())); |
---|
995 | node->set_attribute(XML_REQUESTED_QUANTITY, |
---|
996 | num_to_str( |
---|
997 | imported_product->get_requested_quantity())); |
---|
998 | node->set_attribute(XML_PRICE, |
---|
999 | num_to_str(imported_product->get_price())); |
---|
1000 | } |
---|
1001 | } |
---|
1002 | |
---|
1003 | } |
---|
1004 | |
---|
1005 | xmlpp::Element * arcs = graph->add_child(XML_ARCS); |
---|
1006 | |
---|
1007 | for (Graph::Arc_Iterator it(g); it.has_current(); it.next()) |
---|
1008 | { |
---|
1009 | Graph::Arc * current_arc = it.get_current(); |
---|
1010 | |
---|
1011 | xmlpp::Element * arc = arcs->add_child(XML_ARC); |
---|
1012 | |
---|
1013 | const size_t & src = node_map.find(g.get_src_node(current_arc)); |
---|
1014 | |
---|
1015 | arc->set_attribute(XML_SRC, num_to_str(src)); |
---|
1016 | |
---|
1017 | const size_t & tgt = node_map.find(g.get_tgt_node(current_arc)); |
---|
1018 | |
---|
1019 | arc->set_attribute(XML_TGT, num_to_str(tgt)); |
---|
1020 | |
---|
1021 | IP_Relationship & ip_relationship = current_arc->get_info(); |
---|
1022 | |
---|
1023 | arc->set_attribute(XML_INPUT_ID, |
---|
1024 | num_to_str(ip_relationship.get_input_id())); |
---|
1025 | |
---|
1026 | arc->set_attribute(XML_REQUESTED_QUANTITY, |
---|
1027 | num_to_str(ip_relationship.get_requested_quantity())); |
---|
1028 | |
---|
1029 | arc->set_attribute(XML_PURCHASE_PRICE, |
---|
1030 | num_to_str(ip_relationship.get_purchase_price())); |
---|
1031 | |
---|
1032 | arc->set_attribute(XML_BOUGHT_QUANTITY, |
---|
1033 | num_to_str(ip_relationship.get_bought_quantity())); |
---|
1034 | |
---|
1035 | } |
---|
1036 | |
---|
1037 | doc->write_to_file_formatted(output_file_name, UTF_8); |
---|
1038 | } |
---|
1039 | |
---|
1040 | /** Extrae la información de un grafo de un archivo xml. |
---|
1041 | * |
---|
1042 | * @param file_name nombre del archivo xml. |
---|
1043 | * @param g grafo sobre el cual se va a escribir la información. |
---|
1044 | */ |
---|
1045 | std::string read_graph_from_xml(const std::string & file_name, Graph & g) |
---|
1046 | { |
---|
1047 | xmlpp::DomParser parser(file_name); |
---|
1048 | |
---|
1049 | xmlpp::Document * ptr_doc = parser.get_document(); |
---|
1050 | |
---|
1051 | xmlpp::Element * root = ptr_doc->get_root_node(); |
---|
1052 | |
---|
1053 | xmlpp::Element * node_graph = search_xml_element_by_name(root, XML_GRAPH); |
---|
1054 | |
---|
1055 | I(node_graph != NULL); |
---|
1056 | |
---|
1057 | xmlpp::Node::NodeList children = node_graph->get_children(); |
---|
1058 | |
---|
1059 | Array<Graph::Node *> node_array; |
---|
1060 | |
---|
1061 | for (xmlpp::Node::NodeList::iterator it = children.begin(); |
---|
1062 | it != children.end(); ++it) |
---|
1063 | { |
---|
1064 | xmlpp::Node * curr = *it; |
---|
1065 | |
---|
1066 | if (curr->get_name() == XML_NODES) |
---|
1067 | { |
---|
1068 | xmlpp::Node::NodeList nodes = curr->get_children(); |
---|
1069 | |
---|
1070 | for (xmlpp::Node::NodeList::iterator nit = nodes.begin(); |
---|
1071 | nit != nodes.end(); ++nit) |
---|
1072 | { |
---|
1073 | xmlpp::Element * node = static_cast<xmlpp::Element *>(*nit); |
---|
1074 | |
---|
1075 | if (node->get_name() != XML_NODE) |
---|
1076 | continue; |
---|
1077 | |
---|
1078 | size_t position = std::atol( |
---|
1079 | node->get_attribute_value(XML_POSITION).c_str()); |
---|
1080 | |
---|
1081 | std::shared_ptr<Good> good; |
---|
1082 | |
---|
1083 | xmlpp::Attribute * attr = node->get_attribute(XML_TYPE); |
---|
1084 | |
---|
1085 | Good_Type type = |
---|
1086 | Good_Type(std::atoi(attr->get_value().c_str())); |
---|
1087 | |
---|
1088 | switch (type) |
---|
1089 | { |
---|
1090 | case PRODUCT: |
---|
1091 | { |
---|
1092 | std::unique_ptr<Product> product(new Product); |
---|
1093 | |
---|
1094 | product->set_production_capacity( |
---|
1095 | std::atof( |
---|
1096 | node->get_attribute_value( |
---|
1097 | XML_PRODUCTION_CAPACITY |
---|
1098 | ).c_str() |
---|
1099 | ) |
---|
1100 | ); |
---|
1101 | product->set_production( |
---|
1102 | std::atof( |
---|
1103 | node->get_attribute_value(XML_PRODUCTION).c_str() |
---|
1104 | ) |
---|
1105 | ); |
---|
1106 | product->set_internal_sales( |
---|
1107 | std::atof( |
---|
1108 | node->get_attribute_value(XML_INTERNAL_SALES).c_str() |
---|
1109 | ) |
---|
1110 | ); |
---|
1111 | product->set_external_sales( |
---|
1112 | std::atof( |
---|
1113 | node->get_attribute_value(XML_EXTERNAL_SALES).c_str() |
---|
1114 | ) |
---|
1115 | ); |
---|
1116 | product->set_workday(std::atof( |
---|
1117 | node->get_attribute_value(XML_WORKDAY).c_str() |
---|
1118 | )); |
---|
1119 | product->set_num_administrative_staff(std::atof( |
---|
1120 | node->get_attribute_value( |
---|
1121 | XML_NUM_ADMINISTRATIVE_STAFF).c_str() |
---|
1122 | )); |
---|
1123 | product->set_num_employees(std::atof( |
---|
1124 | node->get_attribute_value(XML_NUM_EMPLOYEES).c_str() |
---|
1125 | )); |
---|
1126 | product->set_price( |
---|
1127 | std::atof(node->get_attribute_value(XML_PRICE).c_str()) |
---|
1128 | ); |
---|
1129 | product->set_other_cost( |
---|
1130 | std::atof( |
---|
1131 | node->get_attribute_value(XML_OTHER_COST).c_str() |
---|
1132 | ) |
---|
1133 | ); |
---|
1134 | |
---|
1135 | good = std::shared_ptr<Good>(product.release()); |
---|
1136 | } |
---|
1137 | break; |
---|
1138 | case INPUT: |
---|
1139 | { |
---|
1140 | std::unique_ptr<Input> input(new Input); |
---|
1141 | |
---|
1142 | input->set_internal_sales( |
---|
1143 | std::atof( |
---|
1144 | node->get_attribute_value(XML_INTERNAL_SALES).c_str() |
---|
1145 | ) |
---|
1146 | ); |
---|
1147 | input->set_external_sales( |
---|
1148 | std::atof( |
---|
1149 | node->get_attribute_value(XML_EXTERNAL_SALES).c_str() |
---|
1150 | ) |
---|
1151 | ); |
---|
1152 | input->set_price( |
---|
1153 | std::atof(node->get_attribute_value(XML_PRICE).c_str()) |
---|
1154 | ); |
---|
1155 | |
---|
1156 | good = std::shared_ptr<Good>(input.release()); |
---|
1157 | } |
---|
1158 | break; |
---|
1159 | case IMPORTED_PRODUCT: |
---|
1160 | { |
---|
1161 | std::unique_ptr<Imported_Product> |
---|
1162 | imported_product(new Imported_Product); |
---|
1163 | |
---|
1164 | imported_product->set_imports( |
---|
1165 | std::atof( |
---|
1166 | node->get_attribute_value(XML_IMPORTS).c_str() |
---|
1167 | ) |
---|
1168 | ); |
---|
1169 | imported_product->set_sale( |
---|
1170 | std::atof( |
---|
1171 | node->get_attribute_value(XML_SALE).c_str() |
---|
1172 | ) |
---|
1173 | ); |
---|
1174 | imported_product->set_requested_quantity( |
---|
1175 | std::atof( |
---|
1176 | node->get_attribute_value( |
---|
1177 | XML_REQUESTED_QUANTITY |
---|
1178 | ).c_str() |
---|
1179 | ) |
---|
1180 | ); |
---|
1181 | imported_product->set_price( |
---|
1182 | std::atof(node->get_attribute_value(XML_PRICE).c_str()) |
---|
1183 | ); |
---|
1184 | |
---|
1185 | good = std::shared_ptr<Good>(imported_product.release()); |
---|
1186 | } |
---|
1187 | } |
---|
1188 | |
---|
1189 | good->set_company_rif( |
---|
1190 | node->get_attribute_value(XML_COMPANY_RIF) |
---|
1191 | ); |
---|
1192 | good->set_company_name( |
---|
1193 | node->get_attribute_value(XML_COMPANY_NAME).c_str() |
---|
1194 | ); |
---|
1195 | good->set_company_location( |
---|
1196 | node->get_attribute_value(XML_COMPANY_LOCATION).c_str() |
---|
1197 | ); |
---|
1198 | good->set_nationality( |
---|
1199 | node->get_attribute_value(XML_COMPANY_NATIONALITY) |
---|
1200 | ); |
---|
1201 | |
---|
1202 | good->set_id(std::atol( |
---|
1203 | node->get_attribute_value(XML_PRODUCT_ID).c_str()) |
---|
1204 | ); |
---|
1205 | good->set_name(node->get_attribute_value(XML_PRODUCT_NAME)); |
---|
1206 | good->set_tariff_code( |
---|
1207 | node->get_attribute_value(XML_TARIFF_CODE) |
---|
1208 | ); |
---|
1209 | good->set_measurement_unit( |
---|
1210 | node->get_attribute_value(XML_MEASUREMENT_UNIT) |
---|
1211 | ); |
---|
1212 | good->set_level( |
---|
1213 | std::atoi(node->get_attribute_value(XML_LEVEL).c_str()) |
---|
1214 | ); |
---|
1215 | |
---|
1216 | node_array.touch(position) = g.insert_node(good); |
---|
1217 | } |
---|
1218 | |
---|
1219 | } |
---|
1220 | else if (curr->get_name() == XML_ARCS) |
---|
1221 | { |
---|
1222 | xmlpp::Node::NodeList arcs = curr->get_children(); |
---|
1223 | |
---|
1224 | for (xmlpp::Node::NodeList::iterator ait = arcs.begin(); |
---|
1225 | ait != arcs.end(); ++ait) |
---|
1226 | { |
---|
1227 | xmlpp::Element * arc = static_cast<xmlpp::Element *>(*ait); |
---|
1228 | |
---|
1229 | if (arc->get_name() != XML_ARC) |
---|
1230 | continue; |
---|
1231 | |
---|
1232 | size_t src = |
---|
1233 | std::atol(arc->get_attribute_value(XML_SRC).c_str()); |
---|
1234 | |
---|
1235 | size_t tgt = |
---|
1236 | std::atol(arc->get_attribute_value(XML_TGT).c_str()); |
---|
1237 | |
---|
1238 | IP_Relationship ip_relationship; |
---|
1239 | |
---|
1240 | ip_relationship.set_input_id( |
---|
1241 | std::atol(arc->get_attribute_value(XML_INPUT_ID).c_str()) |
---|
1242 | ); |
---|
1243 | |
---|
1244 | ip_relationship.set_requested_quantity( |
---|
1245 | std::atof( |
---|
1246 | arc->get_attribute_value(XML_REQUESTED_QUANTITY).c_str() |
---|
1247 | ) |
---|
1248 | ); |
---|
1249 | |
---|
1250 | ip_relationship.set_purchase_price( |
---|
1251 | std::atof( |
---|
1252 | arc->get_attribute_value(XML_PURCHASE_PRICE).c_str() |
---|
1253 | ) |
---|
1254 | ); |
---|
1255 | |
---|
1256 | ip_relationship.set_bought_quantity( |
---|
1257 | std::atof( |
---|
1258 | arc->get_attribute_value(XML_BOUGHT_QUANTITY).c_str() |
---|
1259 | ) |
---|
1260 | ); |
---|
1261 | |
---|
1262 | Graph::Node * s = node_array.access(src); |
---|
1263 | |
---|
1264 | Graph::Node * t = node_array.access(tgt); |
---|
1265 | |
---|
1266 | g.insert_arc(s, t, ip_relationship); |
---|
1267 | } |
---|
1268 | } |
---|
1269 | } |
---|
1270 | |
---|
1271 | xmlpp::Element * year = search_xml_element_by_name(root, YEAR); |
---|
1272 | I(year != NULL); |
---|
1273 | return year->get_attribute_value(VALUE); |
---|
1274 | } |
---|
1275 | |
---|
1276 | struct Write_Exogenous_Variables_Simulation_Attributes |
---|
1277 | { |
---|
1278 | xmlpp::Element * exo_var; |
---|
1279 | |
---|
1280 | Write_Exogenous_Variables_Simulation_Attributes(xmlpp::Element * _exo_var) |
---|
1281 | : exo_var(_exo_var) |
---|
1282 | { |
---|
1283 | // Empty |
---|
1284 | } |
---|
1285 | |
---|
1286 | void operator () (Exogenous_Variables_Simulation_Attributes & st) |
---|
1287 | { |
---|
1288 | xmlpp::Element * state = exo_var->add_child(XML_SIMULATED_STATE); |
---|
1289 | |
---|
1290 | state->set_attribute(XML_STATE_NUMBER, num_to_str(st.state_number)); |
---|
1291 | |
---|
1292 | state->set_attribute(XML_RATE_OF_CHANGE_OF_SALARY, |
---|
1293 | num_to_str(st.rate_of_change_of_salary)); |
---|
1294 | |
---|
1295 | state->set_attribute(XML_RATE_OF_GAIN, num_to_str(st.rate_of_gain)); |
---|
1296 | |
---|
1297 | state->set_attribute(XML_RATE_OF_PRICE_CHANGE, |
---|
1298 | num_to_str(st.rate_of_price_change)); |
---|
1299 | |
---|
1300 | state->set_attribute(XML_RATE_OF_CHANGE_IN_FINAL_DEMAND, |
---|
1301 | num_to_str(st.rate_of_change_in_final_demand)); |
---|
1302 | |
---|
1303 | state->set_attribute(XML_NOMINAL_EXCHANGE_RATE, |
---|
1304 | num_to_str(st.nominal_exchange_rate)); |
---|
1305 | |
---|
1306 | state->set_attribute(XML_UT, num_to_str(st.UT)); |
---|
1307 | } |
---|
1308 | }; |
---|
1309 | |
---|
1310 | /** Escribe sobre un archivo xml los valores de la única instancia de |
---|
1311 | * variables exógenas. |
---|
1312 | * |
---|
1313 | * @param input_file_name nombre del archivo donde hay información base para |
---|
1314 | * el nuevo archivo. |
---|
1315 | * @param output_file_name nombre del archivo en el cual se escribirá la |
---|
1316 | * las información base extraída del archivo original más las variables |
---|
1317 | * exógenas. |
---|
1318 | */ |
---|
1319 | void add_exogenous_variables_to_xml(const std::string & input_file_name, |
---|
1320 | const std::string & output_file_name) |
---|
1321 | { |
---|
1322 | xmlpp::DomParser parser; |
---|
1323 | |
---|
1324 | parser.parse_file(input_file_name); |
---|
1325 | |
---|
1326 | xmlpp::Document * doc = parser.get_document(); |
---|
1327 | |
---|
1328 | I(doc != NULL); |
---|
1329 | |
---|
1330 | xmlpp::Element * root = doc->get_root_node(); |
---|
1331 | |
---|
1332 | I(doc != NULL); |
---|
1333 | |
---|
1334 | remove_white_spaces(root); |
---|
1335 | |
---|
1336 | Exogenous_Variables & ex_var = Exogenous_Variables::get_instance(); |
---|
1337 | |
---|
1338 | xmlpp::Element * node = root->add_child(XML_EXOGENOUS_VARIABLES); |
---|
1339 | |
---|
1340 | node->set_attribute(XML_AVERAGE_SALARY, |
---|
1341 | num_to_str(ex_var.get_average_salary())); |
---|
1342 | |
---|
1343 | node->set_attribute(XML_SIGMA, num_to_str(ex_var.get_sigma())); |
---|
1344 | |
---|
1345 | node->set_attribute(XML_NUM_IT, num_to_str(ex_var.get_num_it())); |
---|
1346 | |
---|
1347 | ex_var.for_each_simulation_attributes( |
---|
1348 | Write_Exogenous_Variables_Simulation_Attributes(node) |
---|
1349 | ); |
---|
1350 | |
---|
1351 | doc->write_to_file_formatted(output_file_name, UTF_8); |
---|
1352 | } |
---|
1353 | |
---|
1354 | /** Carga sobre la única instancia de variables exógenas los valores de un |
---|
1355 | * xml. |
---|
1356 | * |
---|
1357 | * @param file_name nombre del archivo xml. |
---|
1358 | */ |
---|
1359 | void load_exogenous_variables_from_xml(const std::string & file_name) |
---|
1360 | { |
---|
1361 | xmlpp::DomParser parser(file_name); |
---|
1362 | |
---|
1363 | xmlpp::Document * ptr_doc = parser.get_document(); |
---|
1364 | |
---|
1365 | xmlpp::Element * root = ptr_doc->get_root_node(); |
---|
1366 | |
---|
1367 | xmlpp::Element * node = search_xml_element_by_name(root, |
---|
1368 | XML_EXOGENOUS_VARIABLES); |
---|
1369 | |
---|
1370 | I(node != NULL); |
---|
1371 | |
---|
1372 | Exogenous_Variables & ex_var = Exogenous_Variables::get_instance(); |
---|
1373 | |
---|
1374 | ex_var.set_average_salary( |
---|
1375 | std::atof(node->get_attribute_value(XML_AVERAGE_SALARY).c_str()) |
---|
1376 | ); |
---|
1377 | |
---|
1378 | ex_var.set_sigma(std::atof(node->get_attribute_value(XML_SIGMA).c_str())); |
---|
1379 | |
---|
1380 | ex_var.set_num_it(std::atol(node->get_attribute_value(XML_NUM_IT).c_str())); |
---|
1381 | |
---|
1382 | xmlpp::Node::NodeList states = node->get_children(); |
---|
1383 | |
---|
1384 | for (xmlpp::Node::NodeList::iterator it = states.begin(); |
---|
1385 | it != states.end(); ++it) |
---|
1386 | { |
---|
1387 | xmlpp::Element * state = static_cast<xmlpp::Element *>(*it); |
---|
1388 | |
---|
1389 | if (state->get_name() != XML_SIMULATED_STATE) |
---|
1390 | continue; |
---|
1391 | |
---|
1392 | Exogenous_Variables_Simulation_Attributes sim_attr; |
---|
1393 | |
---|
1394 | sim_attr.state_number = std::atol(state->get_attribute_value( |
---|
1395 | XML_STATE_NUMBER).c_str()); |
---|
1396 | |
---|
1397 | sim_attr.rate_of_change_of_salary = |
---|
1398 | std::atof(state->get_attribute_value( |
---|
1399 | XML_RATE_OF_CHANGE_OF_SALARY).c_str()); |
---|
1400 | |
---|
1401 | sim_attr.rate_of_gain = std::atof(state->get_attribute_value( |
---|
1402 | XML_RATE_OF_GAIN).c_str()); |
---|
1403 | |
---|
1404 | sim_attr.rate_of_price_change = |
---|
1405 | std::atof(state->get_attribute_value( |
---|
1406 | XML_RATE_OF_PRICE_CHANGE).c_str()); |
---|
1407 | |
---|
1408 | sim_attr.rate_of_change_in_final_demand = |
---|
1409 | std::atof(state->get_attribute_value( |
---|
1410 | XML_RATE_OF_CHANGE_IN_FINAL_DEMAND).c_str()); |
---|
1411 | |
---|
1412 | sim_attr.nominal_exchange_rate = |
---|
1413 | std::atof(state->get_attribute_value( |
---|
1414 | XML_NOMINAL_EXCHANGE_RATE).c_str()); |
---|
1415 | |
---|
1416 | sim_attr.UT = std::atof(state->get_attribute_value(XML_UT).c_str()); |
---|
1417 | |
---|
1418 | ex_var.add_simulation_attributes(sim_attr); |
---|
1419 | } |
---|
1420 | } |
---|
1421 | |
---|
1422 | struct Write_Product_Simulation_Attributes |
---|
1423 | { |
---|
1424 | xmlpp::Element * states; |
---|
1425 | |
---|
1426 | Write_Product_Simulation_Attributes(xmlpp::Element * _states) |
---|
1427 | : states(_states) |
---|
1428 | { |
---|
1429 | // Empty |
---|
1430 | } |
---|
1431 | |
---|
1432 | void operator () (Product_Simulation_Attributes & st) |
---|
1433 | { |
---|
1434 | xmlpp::Element * state = states->add_child(XML_SIMULATED_STATE); |
---|
1435 | |
---|
1436 | state->set_attribute(XML_STATE_NUMBER, num_to_str(st.state_number)); |
---|
1437 | state->set_attribute(XML_PRODUCTION, num_to_str(st.production)); |
---|
1438 | state->set_attribute(XML_STOCK, num_to_str(st.stock)); |
---|
1439 | state->set_attribute(XML_INTERNAL_SALES, num_to_str(st.internal_sales)); |
---|
1440 | state->set_attribute(XML_EXTERNAL_SALES, num_to_str(st.external_sales)); |
---|
1441 | state->set_attribute(XML_INTERNAL_REQUESTED_QUANTITY, |
---|
1442 | num_to_str(st.internal_requested_quantity)); |
---|
1443 | state->set_attribute(XML_EXTERNAL_REQUESTED_QUANTITY, |
---|
1444 | num_to_str(st.external_requested_quantity)); |
---|
1445 | state->set_attribute(XML_NUM_EMPLOYEES, num_to_str(st.num_employees)); |
---|
1446 | state->set_attribute(XML_DAILY_WAGE, num_to_str(st.daily_wage)); |
---|
1447 | state->set_attribute(XML_OTHER_WAGE, num_to_str(st.other_wage)); |
---|
1448 | state->set_attribute(XML_OTHER_DAILY_WAGE, |
---|
1449 | num_to_str(st.other_daily_wage)); |
---|
1450 | state->set_attribute(XML_DAILY_FEEDING_COUPON, |
---|
1451 | num_to_str(st.daily_feeding_coupon)); |
---|
1452 | state->set_attribute(XML_FEEDING_COUPON, num_to_str(st.feeding_coupon)); |
---|
1453 | state->set_attribute(XML_INTEGRAL_WAGE, num_to_str(st.integral_wage)); |
---|
1454 | state->set_attribute(XML_ADMINISTRATIVE_STAFF_COST, |
---|
1455 | num_to_str(st.administrative_staff_cost)); |
---|
1456 | state->set_attribute(XML_LABOR_COST, num_to_str(st.labor_cost)); |
---|
1457 | state->set_attribute(XML_INPUT_COST, num_to_str(st.input_cost)); |
---|
1458 | state->set_attribute(XML_OTHER_COST, num_to_str(st.other_cost)); |
---|
1459 | state->set_attribute(XML_TOTAL_COST, num_to_str(st.total_cost)); |
---|
1460 | state->set_attribute(XML_UNITARIAN_ADMINISTRATIVE_STAFF_COST, |
---|
1461 | num_to_str(st.unitarian_administrative_staff_cost)); |
---|
1462 | state->set_attribute(XML_UNITARIAN_LABOR_COST, |
---|
1463 | num_to_str(st.unitarian_labor_cost)); |
---|
1464 | state->set_attribute(XML_INPUT_COST_PER_UNIT, |
---|
1465 | num_to_str(st.input_cost_per_unit)); |
---|
1466 | state->set_attribute(XML_OTHER_UNITARIAN_COST, |
---|
1467 | num_to_str(st.other_unitarian_cost)); |
---|
1468 | state->set_attribute(XML_PRICE, num_to_str(st.price)); |
---|
1469 | state->set_attribute(XML_INCOME, num_to_str(st.income)); |
---|
1470 | state->set_attribute(XML_ECONOMIC_STATUS, num_to_str(st.economic_status)); |
---|
1471 | } |
---|
1472 | }; |
---|
1473 | |
---|
1474 | struct Write_Input_Simulation_Attributes |
---|
1475 | { |
---|
1476 | xmlpp::Element * states; |
---|
1477 | |
---|
1478 | Write_Input_Simulation_Attributes(xmlpp::Element * _states) |
---|
1479 | : states(_states) |
---|
1480 | { |
---|
1481 | // Empty |
---|
1482 | } |
---|
1483 | |
---|
1484 | void operator () (Input_Simulation_Attributes & st) |
---|
1485 | { |
---|
1486 | xmlpp::Element * state = states->add_child(XML_SIMULATED_STATE); |
---|
1487 | |
---|
1488 | state->set_attribute(XML_STATE_NUMBER, num_to_str(st.state_number)); |
---|
1489 | state->set_attribute(XML_PRODUCTION, num_to_str(st.production)); |
---|
1490 | state->set_attribute(XML_STOCK, num_to_str(st.stock)); |
---|
1491 | state->set_attribute(XML_INTERNAL_SALES, num_to_str(st.internal_sales)); |
---|
1492 | state->set_attribute(XML_EXTERNAL_SALES, num_to_str(st.external_sales)); |
---|
1493 | state->set_attribute(XML_INTERNAL_REQUESTED_QUANTITY, |
---|
1494 | num_to_str(st.internal_requested_quantity)); |
---|
1495 | state->set_attribute(XML_EXTERNAL_REQUESTED_QUANTITY, |
---|
1496 | num_to_str(st.external_requested_quantity)); |
---|
1497 | state->set_attribute(XML_PRICE, num_to_str(st.price)); |
---|
1498 | } |
---|
1499 | }; |
---|
1500 | |
---|
1501 | struct Write_Imported_Product_Simulation_Attributes |
---|
1502 | { |
---|
1503 | xmlpp::Element * states; |
---|
1504 | |
---|
1505 | Write_Imported_Product_Simulation_Attributes(xmlpp::Element * _states) |
---|
1506 | : states(_states) |
---|
1507 | { |
---|
1508 | // Empty |
---|
1509 | } |
---|
1510 | |
---|
1511 | void operator () (Imported_Product_Simulation_Attributes & st) |
---|
1512 | { |
---|
1513 | xmlpp::Element * state = states->add_child(XML_SIMULATED_STATE); |
---|
1514 | |
---|
1515 | state->set_attribute(XML_STATE_NUMBER, num_to_str(st.state_number)); |
---|
1516 | state->set_attribute(XML_IMPORTS, num_to_str(st.imports)); |
---|
1517 | state->set_attribute(XML_STOCK, num_to_str(st.stock)); |
---|
1518 | state->set_attribute(XML_SALE, num_to_str(st.sales)); |
---|
1519 | state->set_attribute(XML_REQUESTED_QUANTITY, |
---|
1520 | num_to_str(st.requested_quantity)); |
---|
1521 | state->set_attribute(XML_PRICE, num_to_str(st.price)); |
---|
1522 | } |
---|
1523 | }; |
---|
1524 | |
---|
1525 | struct Write_IP_Simulation_Attributes |
---|
1526 | { |
---|
1527 | xmlpp::Element * states; |
---|
1528 | |
---|
1529 | Write_IP_Simulation_Attributes(xmlpp::Element * _states) |
---|
1530 | : states(_states) |
---|
1531 | { |
---|
1532 | // Empty |
---|
1533 | } |
---|
1534 | |
---|
1535 | void operator () (IP_Simulation_Attributes & st) |
---|
1536 | { |
---|
1537 | xmlpp::Element * state = states->add_child(XML_SIMULATED_STATE); |
---|
1538 | |
---|
1539 | state->set_attribute(XML_STATE_NUMBER, num_to_str(st.state_number)); |
---|
1540 | state->set_attribute(XML_PURCHASE_PRICE, num_to_str(st.purchase_price)); |
---|
1541 | state->set_attribute(XML_BOUGHT_QUANTITY, num_to_str(st.bought_quantity)); |
---|
1542 | } |
---|
1543 | }; |
---|
1544 | |
---|
1545 | /** Añade la información de un grafo simulado a un archivo xml. |
---|
1546 | * |
---|
1547 | * @param g grafo que se va a añadir al archivo. |
---|
1548 | * @param input_file_name nombre del archivo donde hay información base para |
---|
1549 | * el nuevo archivo. |
---|
1550 | * @param output_file_name nombre del archivo en el cual se escribirá la |
---|
1551 | * las información base extraída del archivo original más el grafo. |
---|
1552 | */ |
---|
1553 | void add_sim_graph_to_xml(Graph & g, const std::string & input_file_name, |
---|
1554 | const std::string & output_file_name) |
---|
1555 | { |
---|
1556 | xmlpp::DomParser parser; |
---|
1557 | |
---|
1558 | parser.parse_file(input_file_name); |
---|
1559 | |
---|
1560 | xmlpp::Document * doc = parser.get_document(); |
---|
1561 | |
---|
1562 | I(doc != NULL); |
---|
1563 | |
---|
1564 | xmlpp::Element * root = doc->get_root_node(); |
---|
1565 | |
---|
1566 | I(doc != NULL); |
---|
1567 | |
---|
1568 | remove_white_spaces(root); |
---|
1569 | |
---|
1570 | xmlpp::Element * graph = root->add_child(XML_SIMULATED_GRAPH); |
---|
1571 | |
---|
1572 | xmlpp::Element * nodes = graph->add_child(XML_SIMULATED_NODES); |
---|
1573 | |
---|
1574 | Map<Graph::Node *, size_t> node_map; |
---|
1575 | |
---|
1576 | size_t i = 0; // Contador de nodos |
---|
1577 | |
---|
1578 | for (Graph::Node_Iterator it(g); it.has_current(); it.next(), ++i) |
---|
1579 | { |
---|
1580 | Graph::Node * current_node = it.get_current(); |
---|
1581 | |
---|
1582 | node_map.insert(current_node, i); |
---|
1583 | |
---|
1584 | Good * good = current_node->get_info().get(); |
---|
1585 | |
---|
1586 | xmlpp::Element * node = nodes->add_child(XML_SIMULATED_NODE); |
---|
1587 | |
---|
1588 | xmlpp::Element * states = node->add_child(XML_SIMULATED_STATES); |
---|
1589 | |
---|
1590 | node->set_attribute(XML_POSITION, num_to_str(i)); |
---|
1591 | node->set_attribute(XML_LEVEL, num_to_str(good->get_level())); |
---|
1592 | |
---|
1593 | node->set_attribute(XML_COMPANY_RIF, good->get_company_rif()); |
---|
1594 | node->set_attribute(XML_COMPANY_NAME, good->get_company_name()); |
---|
1595 | node->set_attribute(XML_COMPANY_LOCATION, good->get_company_location()); |
---|
1596 | node->set_attribute(XML_COMPANY_NATIONALITY, good->get_nationality()); |
---|
1597 | |
---|
1598 | node->set_attribute(XML_PRODUCT_ID, num_to_str(good->get_id())); |
---|
1599 | node->set_attribute(XML_PRODUCT_NAME, good->get_name()); |
---|
1600 | node->set_attribute(XML_TARIFF_CODE, good->get_tariff_code()); |
---|
1601 | node->set_attribute(XML_MEASUREMENT_UNIT, |
---|
1602 | good->get_measurement_unit()); |
---|
1603 | |
---|
1604 | Good_Type type = good->get_type(); |
---|
1605 | |
---|
1606 | node->set_attribute(XML_TYPE, num_to_str(int(type))); |
---|
1607 | |
---|
1608 | switch (type) |
---|
1609 | { |
---|
1610 | case PRODUCT: |
---|
1611 | { |
---|
1612 | Product * product = static_cast<Product *>(good); |
---|
1613 | |
---|
1614 | node->set_attribute(XML_PRODUCTION_CAPACITY, |
---|
1615 | num_to_str( |
---|
1616 | product->get_production_capacity())); |
---|
1617 | node->set_attribute(XML_PRODUCTION, |
---|
1618 | num_to_str(product->get_production())); |
---|
1619 | node->set_attribute(XML_INTERNAL_SALES, |
---|
1620 | num_to_str(product->get_internal_sales())); |
---|
1621 | node->set_attribute(XML_EXTERNAL_SALES, |
---|
1622 | num_to_str(product->get_external_sales())); |
---|
1623 | node->set_attribute(XML_WORKDAY, |
---|
1624 | num_to_str(product->get_workday())); |
---|
1625 | node->set_attribute(XML_NUM_ADMINISTRATIVE_STAFF, |
---|
1626 | num_to_str(product->get_num_administrative_staff())); |
---|
1627 | node->set_attribute(XML_NUM_EMPLOYEES, |
---|
1628 | num_to_str(product->get_num_employees())); |
---|
1629 | node->set_attribute(XML_PRICE, num_to_str(product->get_price())); |
---|
1630 | node->set_attribute(XML_OTHER_COST, |
---|
1631 | num_to_str(product->get_other_cost())); |
---|
1632 | |
---|
1633 | product->for_each_simulation_attributes( |
---|
1634 | Write_Product_Simulation_Attributes(states) |
---|
1635 | ); |
---|
1636 | } |
---|
1637 | |
---|
1638 | break; |
---|
1639 | case INPUT: |
---|
1640 | { |
---|
1641 | Input * input = static_cast<Input *>(good); |
---|
1642 | |
---|
1643 | node->set_attribute(XML_INTERNAL_SALES, |
---|
1644 | num_to_str(input->get_internal_sales())); |
---|
1645 | node->set_attribute(XML_EXTERNAL_SALES, |
---|
1646 | num_to_str(input->get_external_sales())); |
---|
1647 | node->set_attribute(XML_PRICE, num_to_str(input->get_price())); |
---|
1648 | |
---|
1649 | input->for_each_simulation_attributes( |
---|
1650 | Write_Input_Simulation_Attributes(states) |
---|
1651 | ); |
---|
1652 | } |
---|
1653 | |
---|
1654 | break; |
---|
1655 | case IMPORTED_PRODUCT: |
---|
1656 | { |
---|
1657 | Imported_Product * imported_product = |
---|
1658 | static_cast<Imported_Product *>(good); |
---|
1659 | |
---|
1660 | node->set_attribute(XML_IMPORTS, |
---|
1661 | num_to_str(imported_product->get_imports())); |
---|
1662 | node->set_attribute(XML_SALE, |
---|
1663 | num_to_str(imported_product->get_sale())); |
---|
1664 | node->set_attribute(XML_REQUESTED_QUANTITY, |
---|
1665 | num_to_str( |
---|
1666 | imported_product->get_requested_quantity())); |
---|
1667 | node->set_attribute(XML_PRICE, |
---|
1668 | num_to_str(imported_product->get_price())); |
---|
1669 | |
---|
1670 | imported_product->for_each_simulation_attributes( |
---|
1671 | Write_Imported_Product_Simulation_Attributes(states) |
---|
1672 | ); |
---|
1673 | } |
---|
1674 | } |
---|
1675 | } |
---|
1676 | |
---|
1677 | xmlpp::Element * arcs = graph->add_child(XML_SIMULATED_ARCS); |
---|
1678 | |
---|
1679 | for (Graph::Arc_Iterator it(g); it.has_current(); it.next()) |
---|
1680 | { |
---|
1681 | Graph::Arc * current_arc = it.get_current(); |
---|
1682 | |
---|
1683 | xmlpp::Element * arc = arcs->add_child(XML_SIMULATED_ARC); |
---|
1684 | |
---|
1685 | xmlpp::Element * states = arc->add_child(XML_SIMULATED_STATES); |
---|
1686 | |
---|
1687 | const size_t & src = node_map.find(g.get_src_node(current_arc)); |
---|
1688 | |
---|
1689 | arc->set_attribute(XML_SRC, num_to_str(src)); |
---|
1690 | |
---|
1691 | const size_t & tgt = node_map.find(g.get_tgt_node(current_arc)); |
---|
1692 | |
---|
1693 | arc->set_attribute(XML_TGT, num_to_str(tgt)); |
---|
1694 | |
---|
1695 | IP_Relationship & ip_relationship = current_arc->get_info(); |
---|
1696 | |
---|
1697 | arc->set_attribute(XML_INPUT_ID, |
---|
1698 | num_to_str(ip_relationship.get_input_id())); |
---|
1699 | |
---|
1700 | arc->set_attribute(XML_REQUESTED_QUANTITY, |
---|
1701 | num_to_str(ip_relationship.get_requested_quantity())); |
---|
1702 | |
---|
1703 | arc->set_attribute(XML_PURCHASE_PRICE, |
---|
1704 | num_to_str(ip_relationship.get_purchase_price())); |
---|
1705 | |
---|
1706 | arc->set_attribute(XML_BOUGHT_QUANTITY, |
---|
1707 | num_to_str(ip_relationship.get_bought_quantity())); |
---|
1708 | |
---|
1709 | ip_relationship.for_each_simulation_attributes( |
---|
1710 | Write_IP_Simulation_Attributes(states) |
---|
1711 | ); |
---|
1712 | } |
---|
1713 | |
---|
1714 | doc->write_to_file_formatted(output_file_name, UTF_8); |
---|
1715 | } |
---|
1716 | |
---|
1717 | |
---|
1718 | /** Construye un archivo dot para la visualización del grafo. |
---|
1719 | * |
---|
1720 | * @param g grafo que se va a visualizar. |
---|
1721 | * @param file_name nombre del archivo dot sobre el cual se va a escribir. |
---|
1722 | */ |
---|
1723 | void generate_dot(Graph & g, std::ostream & output) |
---|
1724 | { |
---|
1725 | |
---|
1726 | Map <Graph::Node *, size_t> map; |
---|
1727 | |
---|
1728 | output << "/*\n" << COPYRIGHT << "\n*/\n\n"; |
---|
1729 | |
---|
1730 | output << "/*\n" |
---|
1731 | << " Archivo generado automáticamente por generate_dot en" |
---|
1732 | << " io_manager.H\n\n" |
---|
1733 | << " Autor: Alejandro J. Mujica\n" |
---|
1734 | << "*/\n\n"; |
---|
1735 | |
---|
1736 | output << "digraph\n" |
---|
1737 | << "{\n" |
---|
1738 | << " rankdir = LR;\n\n"; |
---|
1739 | |
---|
1740 | size_t i = 0; |
---|
1741 | |
---|
1742 | for (Graph::Node_Iterator it(g); it.has_current(); it.next(), ++i) |
---|
1743 | { |
---|
1744 | Graph::Node * p = it.get_current(); |
---|
1745 | |
---|
1746 | Good * good = p->get_info().get(); |
---|
1747 | |
---|
1748 | output << " " << i << "[label = \"" << good->to_dot() << "\"]\n"; |
---|
1749 | |
---|
1750 | map.insert(p, i); |
---|
1751 | } |
---|
1752 | |
---|
1753 | for (Graph::Arc_Iterator it(g); it.has_current(); it.next()) |
---|
1754 | { |
---|
1755 | Graph::Arc * a = it.get_current(); |
---|
1756 | |
---|
1757 | Graph::Node * s = g.get_src_node(a); |
---|
1758 | |
---|
1759 | Graph::Node * t = g.get_tgt_node(a); |
---|
1760 | |
---|
1761 | const size_t & si = map.find(s); |
---|
1762 | |
---|
1763 | const size_t & ti = map.find(t); |
---|
1764 | |
---|
1765 | output << " " << si << "->" << ti |
---|
1766 | << "[label = \"" << a->get_info().to_dot() << "\"];\n"; |
---|
1767 | } |
---|
1768 | |
---|
1769 | output << "}"; |
---|
1770 | } |
---|
1771 | }; |
---|
1772 | |
---|
1773 | # endif // IO_MANAGER_H |
---|
1774 | |
---|