FMT 0.9.8
Forest management tools for forest planning
Loading...
Searching...
No Matches
FMTgraph.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2019 Gouvernement du Québec
3
4SPDX-License-Identifier: LiLiQ-R-1.1
5License-Filename: LICENSES/EN/LiLiQ-R11unicode.txt
6*/
7
8#ifndef FMTGRAPH_H
9#define FMTGRAPH_H
10
11#include <boost/graph/adjacency_list.hpp>
12#include <boost/graph/adjacency_matrix.hpp>
13#include <boost/graph/labeled_graph.hpp>
14#include <boost/graph/copy.hpp>
15#include <boost/graph/graph_utility.hpp>
16#include <boost/graph/adj_list_serialize.hpp>
17
19#include "FMTedgeproperties.hpp"
20#include "FMTgraphstats.hpp"
21
22#include "FMToutputnode.hpp"
23#include "FMTdevelopment.hpp"
27#include "FMTschedule.hpp"
28#include "FMTconstraint.hpp"
30#include <boost\unordered_set.hpp>
31#include "FMTpredictor.hpp"
33
34
35
36#include <boost/serialization/split_member.hpp>
37#include <boost/serialization/unordered_map.hpp>
38#include <boost/serialization/vector.hpp>
39#include <boost/serialization/export.hpp>
40#include <boost/range/algorithm_ext/erase.hpp>
41
42#include <memory>
43#include <unordered_map>
44#include <map>
45#include <utility>
46#include <vector>
47#include <queue>
48#include <random>
49
50#include "FMTmodel.hpp"
51#include "FMTaction.hpp"
52#include "FMTtheme.hpp"
53#include "FMTobject.hpp"
54#include <tuple>
55#include <assert.h>
56#include "FMTlookup.hpp"
57#include "boost/graph/graphviz.hpp"
59#include "FMTSerie.hpp"
60
61
63namespace Graph
64{
65
66enum class FMTgraphbuild
67 {
68 schedulebuild = 1,
69 fullbuild = 2,
70 nobuild = 3
71 };
72
73#define FMT_COMMA ,
74
75
76template <class tvertexproperties,class tedgeproperties>
78 {
79 friend class boost::serialization::access;
80 template<class Archive>
81 void save(Archive& ar, const unsigned int version) const
82 {
83 ar & boost::serialization::make_nvp("FMTobject", boost::serialization::base_object<FMTobject>(*this));
84 FMTobject::forcesave(ar, version);
85 ar & BOOST_SERIALIZATION_NVP(data);
86 ar & BOOST_SERIALIZATION_NVP(stats);
87 ar & BOOST_SERIALIZATION_NVP(buildtype);
88 }
89 template<class Archive>
90 void load(Archive& ar, const unsigned int version)
91 {
92 ar & boost::serialization::make_nvp("FMTobject", boost::serialization::base_object<FMTobject>(*this));
93 FMTobject::forcesave(ar, version);
94 ar & BOOST_SERIALIZATION_NVP(data);
95 generatedevelopments();
96 ar & BOOST_SERIALIZATION_NVP(stats);
97 ar & BOOST_SERIALIZATION_NVP(buildtype);
98 }
99 BOOST_SERIALIZATION_SPLIT_MEMBER()
100 protected:
101 typedef boost::adjacency_list< boost::listS,
102 boost::listS,
103 boost::bidirectionalS,
104 tvertexproperties,
105 tedgeproperties,
106 boost::no_property,
109 public:
110 typedef typename boost::graph_traits<FMTadjacency_list>::vertex_descriptor FMTvertex_descriptor;
111 typedef typename boost::graph_traits<FMTadjacency_list>::edge_descriptor FMTedge_descriptor;
112 typedef typename boost::graph_traits<FMTadjacency_list>::in_edge_iterator FMTinedge_iterator;
113 typedef typename boost::graph_traits<FMTadjacency_list>::out_edge_iterator FMToutedge_iterator;
114 typedef typename boost::graph_traits<FMTadjacency_list>::vertex_iterator FMTvertex_iterator;
115 typedef typename boost::graph_traits<FMTadjacency_list>::edge_iterator FMTedge_iterator;
118 protected:
119 FMTgraphbuild buildtype;
120 std::vector<FMTvertex_pair>developments;
124 void updatevarsmap(std::map<int,double>& variables,const int& var,const double& coef) const
125 {
126 try {
127 std::map<int, double>::iterator varit = variables.find(var);
128 if (varit == variables.end())
129 {
130 variables[var] = coef;
131 }
132 else {
133 varit->second += coef;
134 }
135 }
136 catch (...)
137 {
138 _exhandler->raisefromcatch("", "FMTgraph::updatevarsmap", __LINE__, __FILE__);
139 }
140 }
141 typename std::vector<FMTvertex_pair>::iterator getfirstblock()
142 {
143 typename std::vector<FMTvertex_pair>::iterator periodit = developments.begin();
144 try {
145 if (!developments.empty())
146 {
147 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
148 boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data);
149 while (periodit!= developments.end()&&periodit->second==vertex_iterator_end)
150 {
151 ++periodit;
152 }
153 }
154 else {
155 _exhandler->raise(Exception::FMTexc::FMTfunctionfailed,
156 "", "FMTgraph::getfirstblock", __LINE__, __FILE__);
157 }
158 }catch (...)
159 {
160 _exhandler->raisefromcatch("", "FMTgraph::getfirstblock", __LINE__, __FILE__);
161 }
162 return periodit;
163 }
164
165 typename std::vector<FMTvertex_pair>::const_iterator getfirstconstblock() const
166 {
167 typename std::vector<FMTvertex_pair>::const_iterator periodit = developments.begin();
168 try {
169 if (!developments.empty())
170 {
171 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
172 boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data);
173 while (periodit != developments.end() && periodit->second == vertex_iterator_end)
174 {
175 ++periodit;
176 }
177 }
178 else {
179 _exhandler->raise(Exception::FMTexc::FMTfunctionfailed,
180 "Empty graph", "FMTgraph::getfirstconstblock", __LINE__, __FILE__);
181 }
182 }catch (...)
183 {
184 _exhandler->raisefromcatch("", "FMTgraph::getfirstconstblock", __LINE__, __FILE__);
185 }
186 return periodit;
187 }
188 bool isdependant(const FMTvertex_descriptor& descriptor,
189 const int& theactionid,bool& newedge) const
190 {
191 try {
192 newedge = true;
193 if (boost::out_degree(descriptor, data) > 0)
194 {
195 FMToutedge_iterator outit, outend;
196 for (boost::tie(outit, outend) = boost::out_edges(descriptor, data); outit != outend; ++outit)
197 {
198 const FMTbaseedgeproperties& edgeprop = data[*outit];
199 if (edgeprop.getactionID() >= 0)
200 {
201 if (edgeprop.getactionID() < theactionid)
202 {
203 return true;
204 }
206 "Action recursivity " + std::to_string(theactionid)+" ", "FMTgraph::isdependant", __LINE__, __FILE__);
207 newedge = false;
208 }
209 }
210 }
211 }
212 catch (...)
213 {
214 _exhandler->raisefromcatch("", "FMTgraph::isdependant", __LINE__, __FILE__);
215 }
216 return false;
217 }
218 public:
220 Core::FMTobject(),
221 data(),
222 buildtype(FMTgraphbuild::nobuild),
223 developments(),
224 nodescache(),
225 stats()
226 {
227
228 }
229 virtual ~FMTgraph()=default;
230
231 FMTgraph(const FMTgraphbuild lbuildtype) :
232 Core::FMTobject(),
233 data(),
234 buildtype(lbuildtype),
235 developments(),
236 nodescache(),
237 stats()
238 {
239
240 }
241
242 FMTgraph(const FMTgraph& rhs) :
243 Core::FMTobject(rhs),
244 data(rhs.data),
245 buildtype(rhs.buildtype),
246 developments(),
247 nodescache(),
248 stats(rhs.stats)
249 {
250 generatedevelopments();
251 }
252
253 void swap(FMTgraph& rhs)
254 {
255 std::swap(buildtype,rhs.buildtype);
256 nodescache.swap(rhs.nodescache);
257 std::swap(stats,rhs.stats);
258 data.swap(rhs.data);
259 developments.swap(rhs.developments);
260 //std::swap(developments, rhs.developments);
261 }
262
263
264 FMTgraph& operator = (const FMTgraph& rhs)
265 {
266 if (this != &rhs)
267 {
269 buildtype = rhs.buildtype;
270 nodescache = rhs.nodescache;
271 stats = rhs.stats;
272 data = rhs.data;
273 generatedevelopments();
274 }
275 return *this;
276
277 }
278 bool operator == (const FMTgraph& rhs) const
279 {
280 try {
281 if (buildtype == rhs.buildtype &&
282 stats == rhs.stats)
283 {
284 typename std::vector<FMTvertex_pair>::const_iterator devsit = this->getfirstconstblock();
285 size_t location = 0;
286 while (devsit != developments.end())
287 {
288 //for (typename std::vector<FMTvertex_pair>::const_iterator it = developments.at(location).begin(); it != developments.at(location).end(); it++)
289 //{
290 if(((data[*developments.at(location).first].get())!= (rhs.data[*rhs.developments.at(location).first].get()) ||
291 (data[*developments.at(location).second].get()) != (rhs.data[*rhs.developments.at(location).second].get())))
292 {
293 return false;
294 }
295
296 //}
297 ++location;
298 ++devsit;
299 }
300 return true;
301 }
302 }
303 catch (...)
304 {
305 _exhandler->raisefromcatch("", "FMTgraph::operator==", __LINE__, __FILE__);
306 }
307 return false;
308 }
309 bool operator != (const FMTgraph& rhs) const
310 {
311 return (!(*this == rhs));
312 }
314 {
315 std::vector<FMToutputnodecache<FMTvertex_descriptor FMT_COMMA FMTvertex_iterator>>().swap(nodescache);
316 }
318 {
319 std::vector<FMTvertex_pair>().swap(developments);
320 }
322 {
323 return buildtype;
324 }
325 void setbuildtype(const FMTgraphbuild& build)
326 {
327 buildtype = build;
328 }
329 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>>getdevsset(const int& period) const
330 {
331 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>> basedevs;
332 try {
333 FMTvertex_iterator vertex_iterator,vertex_iterator_end;
334 for (boost::tie(vertex_iterator, vertex_iterator_end) = developments.at(period); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
335 {
336 basedevs.insert(Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>(*vertex_iterator, data[*vertex_iterator].get()));
337 }
338 }catch (...)
339 {
340 _exhandler->raisefromcatch("", "FMTgraph::getdevsset", __LINE__, __FILE__);
341 }
342 return basedevs;
343 }
344
346 const boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>>& alldevs) const
347 {
348 return (alldevs.find(Core::FMTlookup<FMTvertex_descriptor,Core::FMTdevelopment>(development)) != alldevs.end());
349 }
350
351 std::queue<FMTvertex_descriptor> initialize(const std::vector<Core::FMTactualdevelopment>& actdevelopments)
352 {
353 std::queue<FMTvertex_descriptor>actives;
354 try {
355 developments.clear();
356 const int startingperiod = actdevelopments.begin()->getperiod();
357 const int actualperiod = startingperiod+1;
358 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
359 //End always stay the same use .end() for non valid period
360 boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data);
361 for (int period = 0 ; period <= actualperiod;++period)
362 {
363 developments.push_back(FMTvertex_pair(vertex_iterator_end,vertex_iterator_end));
364 }
365 const int constraint_id = -1;
366 int edge_id = -1;
367 const double proportion = 100;
368 stats.edges = 0;
369 stats.vertices = 0;
370 std::vector<FMTvertex_descriptor>P0descriptors;
371 P0descriptors.reserve(actdevelopments.size());
372 for (const Core::FMTactualdevelopment& development : actdevelopments)
373 {
374 const FMTvertexproperties properties(development, constraint_id);
375 const FMTvertex_descriptor newvertex = boost::add_vertex(properties, data);
376 P0descriptors.push_back(newvertex);
377 //++vertex_iterator;
378 ++stats.vertices;
379 }
380 size_t poid = 0;
381 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>> devsets;
382 for (const Core::FMTactualdevelopment& development : actdevelopments)
383 {
384 //P1
385 Core::FMTfuturdevelopment P1dev(development);
386 P1dev.setperiod(actualperiod);
387 const FMTvertex_descriptor tovertex = adddevelopment(P1dev, devsets);
388 actives.push(tovertex);
389 //Now set the edge!!
390 const FMTedgeproperties newedge(edge_id, stats.edges, proportion);
391 boost::add_edge(P0descriptors.at(poid), tovertex, newedge, data);
392 ++stats.edges;
393 ++poid;
394 }
395 FMTvertex_iterator firstp0;
396 FMTvertex_iterator lastone;
397 boost::tie(firstp0, vertex_iterator_end) = boost::vertices(data);
398 lastone = firstp0;
399 for (const Core::FMTactualdevelopment& development : actdevelopments)
400 {
401 ++lastone;
402 }
403 developments[startingperiod] = FMTvertex_pair(firstp0, lastone);
404 developments[actualperiod] = FMTvertex_pair(lastone, vertex_iterator_end);
405 }
406 catch (...)
407 {
408 _exhandler->raisefromcatch("", "FMTgraph::initialize", __LINE__, __FILE__);
409 }
410 return actives;
411
412 }
413 // DocString: FMTgraph::build(const Models::FMTmodel&,std::queue<FMTvertex_descriptor>)
420 std::queue<FMTvertex_descriptor> actives,
421 int compressageoperability=1)
422 {
423 FMTgraphstats newstats;
424 try {
425 FMTgraphstats statsdiff(stats);
426 const int actualperiod = getperiod();
427 const bool gotseries = model.useactionserie();
428 const size_t maxseriesize = model.getseriesmaxsize();
429 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>> actualdevs = getdevsset(actualperiod);
430 int action_id = 0;
431 for (const Core::FMTaction& action : model.actions)
432 {
433 std::queue<FMTvertex_descriptor> new_actives;
434 while (!actives.empty())
435 {
436 const FMTvertex_descriptor front_vertex = actives.front();
437 actives.pop();
438 const Graph::FMTgraphvertextoyield vertexinfo = getvertextoyieldinfo(model,front_vertex);
439 const FMTbasevertexproperties& front_properties = data[front_vertex];
440 const Core::FMTdevelopment& active_development = front_properties.get();
441 bool doesnotgrow = false;
442 if (active_development.operable(action,model.yields,&vertexinfo) &&
443 active_development.getage()%compressageoperability==0)
444 {
445 bool gotaserie = false;
446 if (gotseries && keepforserie(front_vertex,
447 (model.actions.cbegin() + action_id),
448 maxseriesize,
449 model.actions,
450 gotaserie))//If true keep it for a next operability
451 //If dont need to keep and not on a serie do the usual thing
452 //If gotserie = true then you are on the right action of the serie...
453 {
454 new_actives.push(front_vertex);
455 continue;
456 }
457 if (gotaserie||action.getname() == "_DEATH")
458 {
459 if (gotaserie && boost::out_degree(front_vertex, data) > 0) // If you are on a serie and you can be operated by other action just throw...
460 {
461 _exhandler->raise(Exception::FMTexc::FMTinvalid_action,
462 std::string(front_properties.get())+
463 " is on a serie for action "+action.getname() + " and have been already operated",
464 "FMTgraph::build", __LINE__, __FILE__);
465 }
466 doesnotgrow = true;
467 }
468 const std::vector<Core::FMTdevelopmentpath> paths = active_development.operate(action, model.transitions[action_id], model.yields, model.themes);
469 addaction(action_id, statsdiff, new_actives, front_vertex, paths, actualdevs, gotseries);
470 }
471 if (!doesnotgrow)
472 {
473 new_actives.push(front_vertex);
474 }
475
476 }
477 actives = new_actives;
478 ++action_id;
479 }
480 const bool typeIIforestmodel = (model.getparameter(Models::FMTintmodelparameters::MATRIX_TYPE) == 2);
481 newstats = naturalgrowth(actives, statsdiff, typeIIforestmodel, gotseries);
482 }
483 catch (...)
484 {
485 _exhandler->raisefromcatch("", "FMTgraph::build", __LINE__, __FILE__);
486 }
487
488 return newstats;
489 }
490
491 bool isnotransfer(const FMTvertex_descriptor& descriptor,size_t outcount = 0) const
492 {
493 try {
494 if (boost::in_degree(descriptor, data) == 1 &&
495 boost::out_degree(descriptor, data) == outcount)
496 {
497 if (outcount<1)
498 {
499 return true;
500 }else {
501 //No Death action please
502 const std::map<int, int>outsvar = getoutvariables(descriptor);
503 return (outsvar.find(-1) != outsvar.end());
504 }
505 }
506
507 }catch (...)
508 {
509 _exhandler->raisefromcatch("", "FMTgraph::isnotransfer", __LINE__, __FILE__);
510 }
511 return false;
512 }
513
514
515
516 double getinproportion(const FMTvertex_descriptor& vertex_descriptor) const
517 {
518 return 1;
519 }
520
521 FMTgraphstats naturalgrowth(std::queue<FMTvertex_descriptor> actives, FMTgraphstats statsdiff,bool typeIImatrix = false,bool splitgrowth = false)
522 {
523 try {
524 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>> nextperiods;
525 FMTvertex_iterator vertex_iterator, vertex_iterator_end,lastoperated;
526 boost::tie(vertex_iterator, vertex_iterator_end) = developments.back();
527 lastoperated = vertex_iterator_end;
528 --lastoperated;
529 while (!actives.empty())
530 {
531 const FMTvertex_descriptor front_vertex = actives.front();
532 actives.pop();
533 FMTbasevertexproperties front_properties = data[front_vertex];
534 const Core::FMTdevelopment active_development = front_properties.get();
535 const Core::FMTfuturdevelopment grown_up = active_development.grow();
536 FMTvertex_descriptor next_period = this->adddevelopment(grown_up, nextperiods,splitgrowth); //getset
537 int variableindex = statsdiff.cols;
538 double proportion = 100;
539 if ( (typeIImatrix && isnotransfer(front_vertex)))//do a type II dont need new variable
540 {
541 variableindex = getinvariables(front_vertex).at(0);
542 proportion = getinproportion(front_vertex);
543 }else{ //We need a new variable
544 ++statsdiff.cols;
545 }
546 const FMTedgeproperties newedge(-1, variableindex,proportion);
547 boost::add_edge(front_vertex, next_period, newedge, data);
548 ++stats.edges;
549 }
550 ++lastoperated;
551 developments.back() = FMTvertex_pair(vertex_iterator, lastoperated);
552 developments.push_back(FMTvertex_pair(lastoperated, vertex_iterator_end));
553 rebasecache();
554 }
555 catch (...)
556 {
557 _exhandler->raisefromcatch("", "FMTgraph::naturalgrowth", __LINE__, __FILE__);
558 }
559 return (statsdiff - stats);
560
561 }
562
563 std::vector<const Core::FMTdevelopment*> nochoice(const Core::FMTmask& basemask, const int& death_id) const
564 {
565 std::vector<const Core::FMTdevelopment*>noactions;
566 try {
567 FMTvertex_iterator vertexit, vertexend;
568 for (boost::tie(vertexit, vertexend) = developments.at(getfirstperiod()); vertexit != vertexend; ++vertexit)
569 {
570 const Core::FMTdevelopment& base_dev = data[*vertexit].get();
571 if (base_dev.getmask().issubsetof(basemask))
572 {
573 std::queue<FMTvertex_descriptor>tocheck;
574 FMToutedge_pair edge_pair;
575 for (edge_pair = boost::out_edges(*vertexit, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
576 {
577 const FMTvertex_descriptor descriptor = boost::target(*edge_pair.first, data);
578 tocheck.push(descriptor);
579 }
580 bool got_choice = false;
581 while (!tocheck.empty() && !got_choice)
582 {
583 const FMTvertex_descriptor& source_descritor = tocheck.front();
584 for (edge_pair = boost::out_edges(source_descritor, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
585 {
586 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
587 const int action_id = edgeprop.getactionID();
588 if (action_id != -1 && action_id != death_id)
589 {
590 got_choice = true;
591 }
592 else {
593 const FMTvertex_descriptor target_descriptor = boost::target(*edge_pair.first, data);
594 tocheck.push(target_descriptor);
595 }
596 }
597 tocheck.pop();
598 }
599 if (!got_choice)
600 {
601 noactions.push_back(&base_dev);
602 }
603 }
604 }
605 }
606 catch (...)
607 {
608 _exhandler->raisefromcatch("", "FMTgraph::nochoice", __LINE__, __FILE__);
609 }
610 return noactions;
611
612 }
613
614
615
616 void getvariablenames(const std::vector<Core::FMTaction>& actions, std::vector<std::string>& colnames) const
617 {
618 try {
619 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
620 const std::string toremove = "+-/*";
621 size_t verticies_id = 0;
622 for (boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data); vertex_iterator != vertex_iterator_end;++vertex_iterator)
623 {
624 std::string basename=std::string(Core::FMTdevelopment(data[*vertex_iterator].get()));
625 const std::string vertexid = "_V"+std::to_string(verticies_id);
626 boost::remove_erase_if(basename, boost::is_any_of(toremove));
627 FMToutedge_iterator outit, outend;
628 for (boost::tie(outit, outend) = boost::out_edges(*vertex_iterator,data);outit!=outend;++outit)
629 {
630 std::string actionname = "EVO";
631 const int variableid = data[*outit].getvariableID();
632 if (colnames.at(variableid).empty())
633 {
634 const int actionid = data[*outit].getactionID();
635 if (actionid >=0)
636 {
637 actionname = actions.at(actionid).getname();
638 }
639 colnames[variableid] = basename + actionname + vertexid;
640 }
641 }
642 ++verticies_id;
643 }
644 }
645 catch (...)
646 {
647 _exhandler->raisefromcatch("", "FMTgraph::getvariablenames", __LINE__, __FILE__);
648 }
649 }
650
651 /*void cleannodecaching(unsigned long long minbytes= 10000000000) const//5 Go max
652 {
653 try {
654 if (!nodescache.empty()&& boost::num_vertices(data)>1000000)
655 {
656 unsigned long long potsize = 0;
657 for (reversecachenodeit cacheit = nodescache.rbegin(); cacheit != nodescache.rend(); ++cacheit)
658 {
659 potsize += cacheit->getpotentialsize();
660 }
661 if (potsize>= minbytes)
662 {
663 unsigned long long avmemory = FMTobject::getavailablememory();
664 if (avmemory < minbytes)
665 {
666 unsigned long long rest = (minbytes - avmemory);
667 unsigned long long totalclean = 1;
668 while (totalclean >= 1 && rest > 0)
669 {
670 totalclean = 0;
671 for (reversecachenodeit cacheit = nodescache.rbegin(); cacheit != nodescache.rend(); ++cacheit)
672 {
673 const unsigned long long lastclean = cacheit->removelargest();
674 rest -= lastclean;
675 totalclean += lastclean;
676 if (lastclean > 0)
677 {
678 break;
679 }
680
681 }
682 }
683 }
684 }
685 }
686 }catch (...)
687 {
688 _exhandler->raisefromcatch("", "FMTgraph::cleannodecaching", __LINE__, __FILE__);
689 }
690 }*/
691
692 void gettransferrownames(std::vector<std::string>& rownames) const
693 {
694 try {
695 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
696 const std::string toremove = "+-/*";
697 size_t verticies_id = 0;
698 for (boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
699 {
700 const int rowid = data[*vertex_iterator].getconstraintID();
701 if (rowid>=0)
702 {
703 const std::string vertexid = "_V" + std::to_string(verticies_id);
704 std::string name = std::string(Core::FMTdevelopment(data[*vertex_iterator].get()));
705 boost::remove_erase_if(name, boost::is_any_of(toremove));
706 rownames[rowid] = name + vertexid;
707 }
708 ++verticies_id;
709 }
710 }
711 catch (...)
712 {
713 _exhandler->raisefromcatch("", "FMTgraph::gettransferrownames", __LINE__, __FILE__);
714 }
715 }
716
717
718 std::vector<Core::FMTactualdevelopment> getperiodstopdev(const int location, const double* actual_solution) const
719 {
720 std::vector<Core::FMTactualdevelopment>all_period_stop_devs;
721 try {
722 FMTvertex_iterator vertexit, vertexend;
723 for (boost::tie(vertexit, vertexend) = developments.at(location); vertexit != vertexend; ++vertexit)
724 {
725 if (periodstop(*vertexit))
726 {
727 const double area = inarea(*vertexit, actual_solution);
728 const FMTbasevertexproperties& vetexprop = data[*vertexit];
729 all_period_stop_devs.push_back(Core::FMTactualdevelopment(vetexprop.get(),area));
730 }
731 }
732 }
733 catch (...)
734 {
735 _exhandler->raisefromcatch("", "FMTgraph::getperiodstopdev", __LINE__, __FILE__);
736 }
737 return all_period_stop_devs;
738
739 }
740 std::map<std::string, double> getoutput(const Models::FMTmodel& model, const Core::FMToutput& output,
741 int period, const double* solution, Core::FMToutputlevel level = Core::FMToutputlevel::standard) const
742 {
743 Core::FMTtheme targettheme;
744 std::vector<std::string>target_attributes;
745 std::map<std::string, double>results;
746 try {
747 if(output.targetthemeid() < 0 && !(level == Core::FMToutputlevel::developpement))
748 {
750 }
752 {
754 {
755 target_attributes = output.getdecomposition(model.themes);
756 if (!target_attributes.empty() && level == Core::FMToutputlevel::standard)
757 {
758 targettheme = output.targettheme(model.themes);
759 }
760 }
761 target_attributes.push_back("Total");
762 for (const std::string& attribute : target_attributes)
763 {
764 results[attribute] = 0;
765 }
766 }
767 std::vector<std::string> equation;
768 if (output.canbenodesonly())
769 {
770 for (const Core::FMToutputnode& output_node : output.getnodes(equation))
771 {
772 const std::map<std::string, double> srcvalues = getsource(model, output_node, period, targettheme, solution, level);
774 {
775 for (std::map<std::string, double>::const_iterator mit = srcvalues.begin(); mit != srcvalues.end(); mit++)
776 {
777 if (results.find(mit->first) == results.end())
778 {
779 results[mit->first] = 0;
780 }
781 results[mit->first] += mit->second;
782 }
783 }
784 else {
785 for (const std::string& attribute : target_attributes)
786 {
787 results[attribute] += srcvalues.at(attribute);
788 }
789 }
790 }
791 }else {
792 std::map<std::string, std::vector<std::string>>allequations;
793 const std::vector<Core::FMToutputnode> allnodes = output.getnodes(equation,1, false,period);
794
795
796 if (allnodes.empty())
797 {
799 {
801 "Cannot get level values by developement",
802 "FMTgraph::getoutput", __LINE__, __FILE__);
803 }
804 allequations["Total"] = equation;
805
806 }else {
807 size_t outid = 0;
808 for (const Core::FMToutputnode& output_node : allnodes)
809 {
810 const std::map<std::string, double> srcvalues = getsource(model, output_node, period, targettheme, solution, level);
811 output_node.fillupequation(allequations, srcvalues, equation, outid);
812 ++outid;
813 }
814 }
815 output.fillfromshuntingyard(equation,results, allnodes, allequations);
816 }
817
818 }
819 catch (...)
820 {
821 _exhandler->raisefromcatch("For output: "+std::string(output), "FMTgraph::getoutput", __LINE__, __FILE__);
822 }
823
824 return results;
825
826 }
828 const boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>>& alldevs) const
829 {
831 return alldevs.find(tofind)->memoryobject;
832 }
834 {
835 return data[descriptor].get();
836 }
838 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor,Core::FMTdevelopment>>& alldevs,bool forcenewone=false)
839 {
840 try {
841 if (!this->containsdevelopment(futurdevelopement, alldevs)||forcenewone)
842 {
843 const int constraint_id = -1;
844 const FMTvertexproperties properties(futurdevelopement, constraint_id);
845 FMTvertex_descriptor newvertex = boost::add_vertex(properties, data);
846 alldevs.insert(Core::FMTlookup<FMTvertex_descriptor,Core::FMTdevelopment>(newvertex,data[newvertex].get()));
847 ++stats.vertices;
848 return newvertex;
849 }
850 }
851 catch (...)
852 {
853 _exhandler->raisefromcatch("", "FMTgraph::adddevelopment", __LINE__, __FILE__);
854 }
855 return getdevelopment(futurdevelopement, alldevs);
856
857 }
859 {
860 FMTvertex_descriptor newvertex = data.null_vertex();
861 try {
862 const int constraint_id = -1;
863 const FMTvertexproperties properties(futurdevelopement, constraint_id);
864 newvertex = boost::add_vertex(properties, data);
865 ++stats.vertices;
866 }catch (...)
867 {
868 _exhandler->raisefromcatch("", "FMTgraph::adddevelopment", __LINE__, __FILE__);
869 }
870 return newvertex;
871 }
872
873
874 size_t hash(size_t seed = 0) const
875 {
876 try {
877 boost::hash_combine(seed, boost::hash<Core::FMTdevelopment>()(data[*developments.at(0).first].get()));
878 FMTedge_iterator edge_iterator, edge_iterator_end;
879 for (boost::tie(edge_iterator, edge_iterator_end) = boost::edges(data); edge_iterator != edge_iterator_end; ++edge_iterator)
880 {
881 const FMTbaseedgeproperties& edgeprop = data[*edge_iterator];
882 boost::hash_combine(seed, edgeprop.getactionID());
883 }
884 }
885 catch (...)
886 {
887 _exhandler->raisefromcatch("", "FMTgraph::hash", __LINE__, __FILE__);
888 }
889 return seed;
890
891 }
892 void addaction(const int& actionID,
893 FMTgraphstats& statsdiff,
894 std::queue<FMTvertex_descriptor>& actives,
895 const FMTvertex_descriptor& out_vertex,
896 const std::vector<Core::FMTdevelopmentpath>& paths,
898 bool inserie = false)
899 {
900 try {
901 //int variable_id = statsdiff.cols;
902 //++statsdiff.cols;
903 //std::vector<FMTvertex_descriptor>active_vertex;
904 bool newchoice = false;
905 for (const Core::FMTdevelopmentpath& devpath : paths)
906 {
907 FMTvertex_descriptor tovertex;
908 bool newedge = true;
909 if (!this->containsdevelopment(*devpath.development,devsets))
910 {
911
912 tovertex = this->adddevelopment(*devpath.development,devsets);
913 actives.push(tovertex);
914 //newedge = true;
915 }else {
916 tovertex = this->adddevelopment(*devpath.development, devsets);
917 if (inserie||isdependant(tovertex, actionID, newedge))
918 {
919 tovertex = this->adddevelopment(*devpath.development, devsets, true);
920 actives.push(tovertex);
921 }
922 }
923 if (newedge)
924 {
925 const FMTedgeproperties newedge(actionID, statsdiff.cols, devpath.proportion);
926 boost::add_edge(out_vertex, tovertex, newedge, data);
927 ++stats.edges;
928 newchoice = true;
929 }
930
931 }
932 if (newchoice)
933 {
934 ++statsdiff.cols;
935 }
936 }
937 catch (...)
938 {
939 _exhandler->raisefromcatch("", "FMTgraph::addaction", __LINE__, __FILE__);
940 }
941 }
942 void addaction(const int& actionID,
943 FMTgraphstats& statsdiff,
944 std::queue<FMTvertex_descriptor>& actives,
945 const FMTvertex_descriptor& out_vertex,
946 const std::vector<Core::FMTdevelopmentpath>& paths)
947 {
948 try {
949 int variable_id = statsdiff.cols;
950 ++statsdiff.cols;
951 std::vector<FMTvertex_descriptor>active_vertex;
952 for (const Core::FMTdevelopmentpath& devpath : paths)
953 {
954 const FMTedgeproperties newedge(actionID, variable_id, devpath.proportion);
955 const FMTvertex_descriptor tovertex = this->adddevelopment(*devpath.development);
956 actives.push(tovertex);
957 boost::add_edge(out_vertex, tovertex, newedge, data);
958 ++stats.edges;
959 }
960 }
961 catch (...)
962 {
963 _exhandler->raisefromcatch("", "FMTgraph::addaction", __LINE__, __FILE__);
964 }
965 }
966
967
968 double outarea(const FMTvertex_descriptor& out_vertex,
969 const int& actionID, const double*& solution) const
970 {
971 double value = 0;
972 try{
973 FMToutedge_iterator outedge_iterator, outedge_end;
974
975 for (boost::tie(outedge_iterator, outedge_end) = boost::out_edges(out_vertex, data); outedge_iterator != outedge_end; ++outedge_iterator)
976 {
977 const FMTbaseedgeproperties& edgeprop = data[*outedge_iterator];
978 if (edgeprop.getactionID() == actionID)
979 {
980
981 value += *(solution + edgeprop.getvariableID()) * (edgeprop.getproportion() / 100);
982 }
983 }
984
985 }
986 catch (...)
987 {
988 _exhandler->raisefromcatch("", "FMTgraph::outarea", __LINE__, __FILE__);
989 }
990 return value;
991 }
992
994 {
995 try {
996 FMTinedge_iterator inedge_iterator, inedge_end;
997 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
998 {
999 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1000 if (edgeprop.getactionID() < 0)
1001 {
1002 return boost::source(*inedge_iterator, data);
1003 }
1004 }
1005 }catch (...)
1006 {
1007 _exhandler->raisefromcatch("", "FMTgraph::getgrowthsource", __LINE__, __FILE__);
1008 }
1009 return FMTvertex_descriptor();
1010 }
1011
1012 std::vector<FMTvertex_descriptor> getactionsources(const FMTvertex_descriptor& out_vertex,const int& actionid) const
1013 {
1014 std::vector<FMTvertex_descriptor> vsources;
1015 try {
1016 FMTinedge_iterator inedge_iterator, inedge_end;
1017 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1018 {
1019 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1020 if (edgeprop.getactionID() == actionid)
1021 {
1022 vsources.push_back(boost::source(*inedge_iterator, data));
1023 }
1024 }
1025 }catch (...)
1026 {
1027 _exhandler->raisefromcatch("", "FMTgraph::getactionsources", __LINE__, __FILE__);
1028 }
1029 return vsources;
1030 }
1031
1032 double inarea(const FMTvertex_descriptor& out_vertex,
1033 const double*& solution,int actionid = -1, bool growth = false) const
1034 {
1035 double area = 0;
1036 try{
1037 FMTinedge_iterator inedge_iterator, inedge_end;
1038 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1039 {
1040 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1041 if (edgeprop.getactionID() == actionid || !growth)
1042 {
1043 area += *(solution + edgeprop.getvariableID()) * (edgeprop.getproportion() / 100);
1044 }
1045 }
1046 }catch (...)
1047 {
1048 _exhandler->raisefromcatch("", "FMTgraph::inarea", __LINE__, __FILE__);
1049 }
1050 return area;
1051 }
1052 bool periodstart(const FMTvertex_descriptor& out_vertex) const
1053 {
1054 try {
1055 FMTinedge_iterator inedge_iterator, inedge_end;
1056 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1057 {
1058 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1059 if (edgeprop.getactionID() == -1)
1060 {
1061 return true;
1062 }
1063 }
1064 }
1065 catch (...)
1066 {
1067 _exhandler->raisefromcatch("", "FMTgraph::periodstart", __LINE__, __FILE__);
1068 }
1069 return false;
1070 }
1071
1072 bool onlypertiodstart(const FMTvertex_descriptor& out_vertex) const
1073 {
1074 try {
1075 if (boost::in_degree(out_vertex, data) == 1)
1076 {
1077 FMTinedge_iterator inedge_iterator, inedge_end;
1078 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1079 {
1080 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1081 if (edgeprop.getactionID() == -1)
1082 {
1083 return true;
1084 }
1085 }
1086 }
1087 }
1088 catch (...)
1089 {
1090 _exhandler->raisefromcatch("", "FMTgraph::onlypertiodstart", __LINE__, __FILE__);
1091 }
1092 return false;
1093
1094 }
1095
1096 int getmaximalock(const int& period)
1097 {
1098 int lock = 0;
1099 try {
1100 FMTvertex_iterator vertexit, vertexend;
1101 for (boost::tie(vertexit, vertexend) = developments.at(period);vertexit!=vertexend;++vertexit)
1102 {
1103 const Core::FMTdevelopment& dev = data[*vertexit].get();
1104 if (dev.getlock()>lock)
1105 {
1106 lock = dev.getlock();
1107 }
1108 }
1109 }catch (...)
1110 {
1111 _exhandler->raisefromcatch("", "FMTgraph::getmaximalock", __LINE__, __FILE__);
1112 }
1113 return lock;
1114 }
1115
1116 bool periodstop(const FMTvertex_descriptor& out_vertex) const
1117 {
1118 try {
1119 FMToutedge_iterator outedge_iterator, outedge_end;
1120 const FMTbasevertexproperties& source_properties = data[out_vertex];
1121 if ((source_properties.get().getperiod()) == 0)
1122 {
1123 return true;
1124 }
1125 for (boost::tie(outedge_iterator, outedge_end) = boost::out_edges(out_vertex, data); outedge_iterator != outedge_end; ++outedge_iterator)
1126 {
1127 const FMTbaseedgeproperties& edgeprop = data[*outedge_iterator];
1128 if (edgeprop.getactionID() == -1)
1129 {
1130 return true;
1131 }
1132 }
1133 }
1134 catch (...)
1135 {
1136 _exhandler->raisefromcatch("", "FMTgraph::periodstop", __LINE__, __FILE__);
1137 }
1138 return false;
1139 }
1140 std::vector<Core::FMTdevelopmentpath> getpaths(const FMTvertex_descriptor& out_vertex,
1141 const int& actionID) const
1142 {
1143 std::vector<Core::FMTdevelopmentpath>paths;
1144 try {
1145 for (FMToutedge_pair edge_pair = boost::out_edges(out_vertex, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
1146 {
1147 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
1148 if (edgeprop.getactionID() == actionID)
1149 {
1150 const FMTbasevertexproperties& vertex_target = data[target(*edge_pair.first, data)];
1151 paths.push_back(Core::FMTdevelopmentpath(vertex_target.get(), edgeprop.getproportion()));
1152 }
1153 }
1154 }
1155 catch (...)
1156 {
1157 _exhandler->raisefromcatch("", "FMTgraph::getpaths", __LINE__, __FILE__);
1158 }
1159 return paths;
1160 }
1161 bool isvalidouputnode(const Models::FMTmodel& model, const Core::FMToutputnode& node, std::vector<const Core::FMTaction*>& action_IDS, int period) const
1162 {
1163 try {
1164 if (static_cast<int>(developments.size()) > period)
1165 {
1166 action_IDS = node.source.targets(model.actions);
1167 if (!(period == 0 && !action_IDS.empty()) && !node.source.isnull(model.yields) && !node.factor.isnull(model.yields) && ((!action_IDS.empty() && !node.source.getaction().empty()) || node.source.getaction().empty()))
1168 {
1169 return true;
1170 }
1171 }
1172 }
1173 catch (...)
1174 {
1175 _exhandler->raisefromcatch("", "FMTgraph::isvalidouputnode", __LINE__, __FILE__);
1176 }
1177 return false;
1178 }
1179
1180
1181 bool isvalidgraphnode(const Models::FMTmodel& model, const FMTvertex_descriptor& vertex_descriptor,
1182 const Core::FMToutputnode& node,const std::vector<const Core::FMTaction*>& selected) const
1183 {
1184 try {
1185 const Core::FMTdevelopment& development = data[vertex_descriptor].get();
1186 if (node.source.use(development, model.yields))
1187 {
1188 if (node.source.useinedges())
1189 {
1190 return ((development.getperiod() == 0 || node.source.isaction() || periodstart(vertex_descriptor)) && ((selected.empty() && (node.source.isnextperiod() || !node.source.emptylock())) ||
1191 (((buildtype == FMTgraphbuild::schedulebuild) && development.anyoperable(selected, model.yields, &getvertextoyieldinfo(model, vertex_descriptor))) ||
1192 isanyoperables(vertex_descriptor, development.isanyworthtestingoperability(selected, model.actions)))));
1193 }
1194 else //out edges
1195 {
1196 return isanyoperables(vertex_descriptor, development.isanyworthtestingoperability(selected, model.actions));
1197 }
1198 }
1199 }
1200 catch (...)
1201 {
1202 _exhandler->raisefromcatch("", "FMTgraph::isvalidgraphnode", __LINE__, __FILE__);
1203 }
1204 return false;
1205 }
1206 std::map<int,double> locatenode(const Models::FMTmodel& model,Core::FMToutputnode output_node, int period) const
1207 {
1208 std::map<int, double>emptyreturn;
1209 try {
1210 Core::FMToutputnode tempnode(output_node);
1211 const std::vector<FMTvertex_descriptor>verticies = getnode(model, tempnode, period);
1212 return getvariables(model, tempnode, verticies);
1213 }
1214 catch (...)
1215 {
1216 _exhandler->raisefromcatch("", "FMTgraph::locatenode", __LINE__, __FILE__);
1217 }
1218 return emptyreturn;
1219
1220 }
1221 std::map<std::string,std::map<int,double>> locatenodebytheme(const Models::FMTmodel& model,Core::FMToutputnode output_node, int period) const
1222 {
1223 std::map<std::string,std::map<int,double>> variablesreturn;
1224 //std::vector<std::map<int,double>> variablesreturn;
1225 try {
1226 const std::vector<FMTvertex_descriptor>verticies = getnode(model, output_node, period);
1227 int themetarget = output_node.source.getthemetarget();
1228 if(themetarget<0)
1229 {
1230 variablesreturn["~nothemetargetid~"]=getvariables(model, output_node, verticies);
1231 //variablesreturn.push_back(getvariables(model, output_node, verticies));
1232 }else{
1233 std::map<std::string,std::vector<FMTvertex_descriptor>> orderedtarget;
1234 for (const auto& vert : verticies)
1235 {
1236 const Core::FMTdevelopment& dev = getdevelopment(vert);
1237 const std::string value = dev.getmask().get(model.themes.at(themetarget));
1238 if(orderedtarget.find(value)==orderedtarget.end())
1239 {
1240 orderedtarget[value]=std::vector<FMTvertex_descriptor>();
1241 }
1242 orderedtarget[value].push_back(vert);
1243 }
1244 for (const auto& odtar:orderedtarget)
1245 {
1246 variablesreturn[odtar.first]=getvariables(model,output_node,odtar.second);
1247 //variablesreturn.push_back(getvariables(model,output_node,odtar.second));
1248 }
1249 }
1250 }
1251 catch (...)
1252 {
1253 _exhandler->raisefromcatch("", "FMTgraph::locatenodebytheme", __LINE__, __FILE__);
1254 }
1255 return variablesreturn;
1256
1257 }
1258 std::vector<FMTvertex_descriptor> getnode(const Models::FMTmodel& model, Core::FMToutputnode& output_node, int period) const
1259 {
1260 std::vector<FMTvertex_descriptor>locations;
1261 try {
1262 std::vector<int>targetedperiods;
1263 const int maxperiod = static_cast<int>(developments.size() - 2);
1264 const int node_period = output_node.settograph(targetedperiods, period, maxperiod);
1265 //*_logger << "node of " << node_period<<"dev size "<< developments.size() << "\n";
1266 if (node_period < 0)
1267 {
1268 return locations;
1269 }
1270 if (!output_node.source.isvariablelevel())
1271 {
1272 //constexpr size_t minimalcachedrop = 25;//10 %
1273 std::vector<const Core::FMTaction*> selected;
1274 //*_logger << "node " << std::string(output_node) << " period " << node_period<<" "<< targetedperiods.size() << "\n";
1275 if (isvalidouputnode(model, output_node, selected, node_period))
1276 {
1277 //*_logger << "valid node! " << "\n";
1278
1279 if (nodescache.empty())
1280 {
1281 nodescache.reserve(developments.size());
1282 }
1283 //cleannodecaching();
1284 const bool gotstaticnode = model.isstaticnode(output_node);
1285 for (const int& localnodeperiod : targetedperiods)
1286 {
1287 std::vector<FMTvertex_descriptor> const* descriptors = nullptr;
1288 std::vector<FMTvertex_descriptor>staticdescriptors;
1289 bool exactverticies = false;
1290
1291 if (gotstaticnode)
1292 {
1293 staticdescriptors = getnodebystaticmask(model, output_node, localnodeperiod);
1294 descriptors = &staticdescriptors;
1295 }else {
1296 while (nodescache.size() != developments.size())
1297 {
1298 const size_t devindex = nodescache.size();
1299 nodescache.emplace_back(developments.at(devindex).first, developments.at(devindex).second);
1300 }
1301 descriptors = &nodescache.at(localnodeperiod).getverticies(output_node, model.actions, model.themes, exactverticies);
1302 }
1303 //*_logger << "test? " << gotstaticnode << " " << exactverticies << "\n";
1304 if (exactverticies)
1305 {
1306 locations.reserve(locations.size() + descriptors->size());
1307 locations.insert(locations.end(), descriptors->begin(), descriptors->end());
1308 }else {
1309 std::vector<FMTvertex_descriptor>periodlocations;
1310 //*_logger << "testing on "<< descriptors->size()<<" "<< selected .size()<< "\n";
1311
1312 for (const FMTvertex_descriptor& potential : *descriptors)
1313 {
1314 if (isvalidgraphnode(model, potential, output_node, selected))
1315 {
1316 locations.push_back(potential);
1317 periodlocations.push_back(potential);
1318 }
1319 }
1320 //*_logger << "done on " << periodlocations.size() << "\n";
1321 std::sort(periodlocations.begin(), periodlocations.end());
1322 if (!gotstaticnode)
1323 {
1324 nodescache.at(localnodeperiod).setvalidverticies(output_node, periodlocations);
1325 }
1326 }
1327 }
1328
1329
1330 }
1331
1332 }
1333 }
1334 catch (...)
1335 {
1336 _exhandler->raisefromcatch("", "FMTgraph::getnode", __LINE__, __FILE__);
1337 }
1338 std::sort(locations.begin(), locations.end());
1339 //*_logger << "Output of getnode!" << "\n";
1340 return locations;
1341 }
1342 std::map<int, double> getvariables(const Models::FMTmodel& model, const Core::FMToutputnode& output_node,const std::vector<FMTvertex_descriptor>& verticies) const
1343 {
1344 return std::map<int, double>();
1345 }
1346 bool isanyoperables(const FMTvertex_descriptor& descriptor, const std::vector<bool>& actionsop) const noexcept
1347 {
1348 //try {
1349 if (!actionsop.empty())
1350 {
1351 FMToutedge_pair edge_pair;
1352 for (edge_pair = boost::out_edges(descriptor, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
1353 {
1354 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
1355 const int actionid = edgeprop.getactionID();
1356 if (actionid >= 0 && actionsop.at(actionid))
1357 {
1358 return true;
1359 }
1360 }
1361 }
1362
1363 /*}
1364 catch (...)
1365 {
1366 _exhandler->raisefromcatch("", "FMTgraph::isanyoperables", __LINE__, __FILE__);
1367 }*/
1368 return false;
1369 }
1370
1371
1372
1373 bool anyoperables(const FMTvertex_descriptor& descriptor, const std::vector<int>& action_ids) const
1374 {
1375 try {
1376 if (!action_ids.empty())
1377 {
1378 std::map<int, int> variables = getoutvariables(descriptor);
1379 for (const int& id : action_ids)
1380 {
1381 if (variables.find(id) != variables.end())
1382 {
1383 return true;
1384 }
1385 }
1386 }
1387 }
1388 catch (...)
1389 {
1390 _exhandler->raisefromcatch("", "FMTgraph::anyoperables", __LINE__, __FILE__);
1391 }
1392 return false;
1393 }
1394 std::vector<int>getinvariables(const FMTvertex_descriptor& out_vertex) const
1395 {
1396 std::vector<int>invars;
1397 try {
1398 FMTinedge_iterator inedge_iterator, inedge_end;
1399 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1400 {
1401 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1402 invars.push_back(edgeprop.getvariableID());
1403
1404 }
1405 }
1406 catch (...)
1407 {
1408 _exhandler->raisefromcatch("", "FMTgraph::getinvariables", __LINE__, __FILE__);
1409 }
1410 return invars;
1411 }
1412
1413 std::vector<double>getinproportions(const FMTvertex_descriptor& out_vertex) const
1414 {
1415 std::vector<double>inprops;
1416 try {
1417 FMTinedge_iterator inedge_iterator, inedge_end;
1418 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1419 {
1420 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1421 inprops.push_back(edgeprop.getproportion());
1422
1423 }
1424 }
1425 catch (...)
1426 {
1427 _exhandler->raisefromcatch("", "FMTgraph::getinproportions", __LINE__, __FILE__);
1428 }
1429 return inprops;
1430 }
1431
1432 std::map<int, int>getinidsvariables(const FMTvertex_descriptor& out_vertex) const
1433 {
1434 std::map<int, int> mapping;
1435 try {
1436 FMTinedge_iterator inedge_iterator, inedge_end;
1437 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
1438 {
1439 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
1440 int actionid = edgeprop.getactionID();
1441 //*_logger << actionid << " test "<< edgeprop.getvariableID() <<"\n";
1442 mapping[actionid] = edgeprop.getvariableID();
1443 }
1444 }
1445 catch (...)
1446 {
1447 _exhandler->raisefromcatch("", "FMTgraph::getinidsvariables", __LINE__, __FILE__);
1448 }
1449 return mapping;
1450 }
1451
1452 std::map<int, int> getoutvariables(const FMTvertex_descriptor& out_vertex) const
1453 {
1454 std::map<int, int> mapping;
1455 try {
1456 FMToutedge_pair edge_pair;
1457 for (edge_pair = boost::out_edges(out_vertex, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
1458 {
1459 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
1460 int actionid = edgeprop.getactionID();
1461 mapping[actionid] = edgeprop.getvariableID();
1462 }
1463 }
1464 catch (...)
1465 {
1466 _exhandler->raisefromcatch("", "FMTgraph::getoutvariables", __LINE__, __FILE__);
1467 }
1468 return mapping;
1469 }
1470
1471
1472
1473 std::vector<int>getoutactions(const FMTvertex_descriptor& out_vertex) const
1474 {
1475 std::vector<int>actions;
1476 try {
1477 const size_t outsize = boost::out_degree(out_vertex, data);
1478 if (outsize > 1)
1479 {
1480 actions.reserve(outsize - 1);
1481 FMToutedge_pair edge_pair;
1482 for (edge_pair = boost::out_edges(out_vertex, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
1483 {
1484 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
1485 const int actionid = edgeprop.getactionID();
1486 if ((actionid) >= 0)
1487 {
1488 actions.emplace_back(static_cast<int>(actionid));
1489 }
1490 }
1491 std::sort(actions.begin(), actions.end());
1492 }
1493 }
1494 catch (...)
1495 {
1496 _exhandler->raisefromcatch("", "FMTgraph::getoutactions", __LINE__, __FILE__);
1497 }
1498 return actions;
1499 }
1500 std::vector<const Core::FMTaction*> selectedactions(const Models::FMTmodel& model, const std::vector<int>& action_IDS) const
1501 {
1502 std::vector<const Core::FMTaction*>selected;
1503 try {
1504 if (!action_IDS.empty())
1505 {
1506 selected.resize(action_IDS.size());
1507 int aid = 0;
1508 for (const int & actid : action_IDS)
1509 {
1510 selected[aid] = &model.actions[actid];
1511 ++aid;
1512 }
1513 }
1514 }catch (...)
1515 {
1516 _exhandler->raisefromcatch("", "FMTgraph::selectedactions", __LINE__, __FILE__);
1517 }
1518 return selected;
1519 }
1520 bool constraintlenght(const Core::FMTconstraint& constraint, int& start, int& stop) const
1521 {
1522 try {
1523 int constraintlower = constraint.getperiodlowerbound();
1524 if (constraintlower == std::numeric_limits<int>::max())
1525 {
1526 constraintlower = static_cast<int>((developments.size() - 2));
1527 }
1528 //start = std::max(constraintlower, getfirstactiveperiod() + 1);
1529 //*_logger << "get on" << getfirstperiod() << "\n";
1530 start = std::max(constraintlower, getfirstperiod());
1531 stop = static_cast<int>((constraint.getperiodupperbound() > static_cast<int>((developments.size() - 2))) ? (developments.size() - 2) : constraint.getperiodupperbound());
1532 if (constraint.acrossperiod())
1533 {
1534 --stop;
1535 }
1536 }
1537 catch (...)
1538 {
1539 _exhandler->raisefromcatch("", "FMTgraph::constraintlenght", __LINE__, __FILE__);
1540 }
1541 return (start < static_cast<int>(developments.size()) && start <= stop);
1542 }
1544 {
1545 return stats;
1546 }
1548 {
1549 return &stats;
1550 }
1551 void setstats(const FMTgraphstats& newstats)
1552 {
1553 stats = newstats;
1554 }
1555
1557 std::queue<FMTvertex_descriptor> actives,
1558 const Core::FMTschedule& schedule)
1559 {
1560 FMTgraphstats statsdiff(stats);
1561 try {
1562 //developments.push_back(boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>>());
1563 //developments.back().reserve(actives.size());
1564 const int actualperiod = getperiod();
1565 boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>> actualdevs = getdevsset(actualperiod);
1566 int action_id = 0;
1567 for (const Core::FMTaction& action : model.actions)
1568 {
1569 if (schedule.find(action) != schedule.end())
1570 {
1571 std::queue<FMTvertex_descriptor> new_actives;
1572 while (!actives.empty())
1573 {
1574 const FMTvertex_descriptor front_vertex = actives.front();
1575 actives.pop();
1576 FMTbasevertexproperties front_properties = data[front_vertex];
1577 const Core::FMTdevelopment& active_development = front_properties.get();
1578 bool death = false;
1579 if ((((schedule.at(action)).find(active_development) != (schedule.at(action)).end()) ||
1580 (!action.dorespectlock() && active_development.getlock() != 0 &&
1581 (schedule.at(action)).find(active_development.clearlock()) != (schedule.at(action)).end())))
1582 {
1583 const Graph::FMTgraphvertextoyield vertexinfo = getvertextoyieldinfo(model,front_vertex);
1584 if (active_development.operable(action, model.yields, &vertexinfo))
1585 {
1586 if (action.getname() == "_DEATH")
1587 {
1588 death = true;
1589 }
1590 const std::vector<Core::FMTdevelopmentpath> paths = active_development.operate(action, model.transitions[action_id], model.yields, model.themes);
1591 addaction(action_id, statsdiff, new_actives, front_vertex, paths, actualdevs);
1592 }
1593 }
1594 if (!death)
1595 {
1596 new_actives.push(front_vertex);
1597 }
1598 }
1599 actives = new_actives;
1600 }
1601 ++action_id;
1602 }
1603 }
1604 catch (...)
1605 {
1606 _exhandler->raisefromcatch("", "FMTgraph::buildschedule", __LINE__, __FILE__);
1607 }
1608 const bool typeIIforestmodel = (model.getparameter(Models::FMTintmodelparameters::MATRIX_TYPE) == 2);
1609 return naturalgrowth(actives, statsdiff,typeIIforestmodel);
1610 }
1611
1612
1613
1614 FMTgraphstats eraseperiod(std::vector<int>& deletedconstraints,
1615 std::vector<int>&deletedvariables,
1616 bool keepbounded = false)
1617 {
1618
1619 return getstats();
1620 }
1621 bool empty() const
1622 {
1623 return developments.empty();
1624 }
1625
1626 std::queue<FMTvertex_descriptor> getactiveverticies() const
1627 {
1628 std::queue<FMTvertex_descriptor>actives;
1629 try {
1630 FMTvertex_iterator vertexit, vertexend;
1631 for (boost::tie(vertexit, vertexend) = developments.back(); vertexit != vertexend; ++vertexit)
1632 {
1633 actives.push(*vertexit);
1634 }
1635 }
1636 catch (...)
1637 {
1638 _exhandler->raisefromcatch("", "FMTgraph::getactiveverticies", __LINE__, __FILE__);
1639 }
1640 return actives;
1641 }
1642
1643
1644 const FMTvertex_pair& getperiodverticies(int period) const
1645 {
1646 return developments.at(period);
1647 }
1648
1649 /*lookconst_iterator begin(int period) const
1650 {
1651 return developments.at(period).cbegin();
1652 }
1653
1654 lookconst_iterator end(int period) const
1655 {
1656 return developments.at(period).cend();
1657 }*/
1658 size_t size() const
1659 {
1660 return developments.size();
1661 }
1662 void setconstraintID(const FMTvertex_descriptor& vertex, const int& id)
1663 {
1664
1665 }
1666 bool gettransferrow(const FMTvertex_descriptor& vertex_descriptor,
1667 std::vector<int>&row_starts,
1668 std::vector<int>& cols,
1669 std::vector<double>& cols_value) const
1670 {
1671 return false;
1672 }
1673 void getinitialbounds(std::vector<double>& lower_bounds, std::vector<double>& upper_bounds) const
1674 {
1675 try {
1676
1677 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
1678 for (boost::tie(vertex_iterator, vertex_iterator_end) = developments.at(getfirstactiveperiod()); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
1679 {
1680 const FMTvertex_descriptor descriptor = *vertex_iterator;
1681 const FMTbasevertexproperties& vproperty = data[descriptor];
1682 const std::map<int, int>outs = getoutvariables(descriptor);
1683 lower_bounds[outs.at(-1)] = vproperty.getbaseRHS();
1684 upper_bounds[outs.at(-1)] = vproperty.getbaseRHS();
1685 }
1686 }
1687 catch (...)
1688 {
1689 _exhandler->raisefromcatch("", "FMTgraph::getinitialbounds", __LINE__, __FILE__);
1690 }
1691 }
1692 size_t nedges() const
1693 {
1694 return boost::num_edges(data);
1695 }
1696
1697 std::vector<FMTvertex_descriptor>getnodebystaticmask(
1698 const Models::FMTmodel& model,
1699 const Core::FMToutputnode& node, int period) const
1700 {
1701 std::vector<FMTvertex_descriptor>descriptors;
1702 try {
1703 const Core::FMTmask staticmask = model.getstaticmask(node, true);
1704 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
1705 for (boost::tie(vertex_iterator, vertex_iterator_end)=getperiodverticies(period); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
1706 {
1707 const Core::FMTdevelopment& dev = data[*vertex_iterator].get();
1708 if (dev.getmask().issubsetof(staticmask))
1709 {
1710 descriptors.push_back(*vertex_iterator);
1711 }
1712 }
1713 /*std::queue<FMTvertex_descriptor>activedescriptors;
1714 boost::unordered_set<FMTvertex_descriptor>explored;
1715 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
1716 const typename std::vector<FMTvertex_pair>::const_iterator firstconst = getfirstconstblock();
1717 vertex_iterator_end = firstconst->second;
1718 for (vertex_iterator = firstconst->first; vertex_iterator != vertex_iterator_end; ++vertex_iterator)
1719 {
1720 const Core::FMTdevelopment& dev = data[*vertex_iterator].get();
1721 if (dev.getmask().issubsetof(staticmask))
1722 {
1723 activedescriptors.push(*vertex_iterator);
1724 explored.insert(*vertex_iterator);
1725 }
1726 }
1727 while (!activedescriptors.empty())
1728 {
1729 const FMTvertex_descriptor& active = activedescriptors.front();
1730 FMToutedge_iterator outit, outend;
1731 for (boost::tie(outit, outend) = boost::out_edges(active, data); outit != outend; ++outit)
1732 {
1733 const FMTvertex_descriptor gtarget = boost::target(*outit, data);
1734 if (explored.find(gtarget)==explored.end()&&data[gtarget].get().getperiod()<=period)
1735 {
1736 activedescriptors.push(gtarget);
1737 explored.insert(gtarget);
1738 }
1739 }
1740 const Core::FMTdevelopment& actdev = data[active].get();
1741 if (actdev.getperiod()==period)
1742 {
1743 descriptors.push_back(active);
1744 }
1745 activedescriptors.pop();
1746 }*/
1747 }catch (...)
1748 {
1749 _exhandler->raisefromcatch("For node: " + std::string(node), "FMTgraph::getnodebystaticmask", __LINE__, __FILE__);
1750 }
1751 return descriptors;
1752 }
1753
1754
1755 std::map<std::string, double> getsource(const Models::FMTmodel& model,
1756 const Core::FMToutputnode& node,
1757 int period, const Core::FMTtheme& theme,
1758 const double* solution, Core::FMToutputlevel level = Core::FMToutputlevel::standard) const
1759 {
1760 std::map<std::string, double>emptyreturn;
1761 try{
1762 Core::FMToutputnode tempnode(node);
1763 const std::vector<FMTvertex_descriptor>verticies = getnode(model, tempnode, period);
1764 return getvalues(model, verticies, tempnode, theme, solution, level);
1765 }catch (...)
1766 {
1767 _exhandler->raisefromcatch("For node: "+std::string(node), "FMTgraph::getsource", __LINE__, __FILE__);
1768 }
1769 return emptyreturn;
1770 }
1771
1773 {
1774 try {
1775 return Graph::FMTgraphvertextoyield(model,*this, reinterpret_cast<const void*>(&descriptor));
1776 }catch (...)
1777 {
1778 _exhandler->raisefromcatch("", "FMTgraph::getvertextoyieldinfo", __LINE__, __FILE__);
1779 }
1781 }
1782
1784 {
1785 try {
1786 return reinterpret_cast<const FMTvertex_descriptor*>(info->getvertexptr());
1787 }
1788 catch (...)
1789 {
1790 _exhandler->raisefromcatch("", "FMTgraph::getvertexfromvertexinfo", __LINE__, __FILE__);
1791 }
1792 return nullptr;
1793 }
1794
1795
1796
1797
1798 std::map<std::string, double> getvalues(const Models::FMTmodel& model, const std::vector<FMTvertex_descriptor>& verticies,
1799 const Core::FMToutputnode& node, const Core::FMTtheme& theme,
1800 const double* solution, Core::FMToutputlevel level) const
1801 {
1802 std::map<std::string, double>values;
1803 try {
1804 if (level == Core::FMToutputlevel::standard)
1805 {
1806 for (const std::string& attribute : theme.getbaseattributes())
1807 {
1808 values[attribute] = 0;
1809 }
1810 }
1811 else if (level == Core::FMToutputlevel::totalonly)
1812 {
1813 values["Total"] = 0;
1814 }
1815 if (!verticies.empty())
1816 {
1817 const std::vector<const Core::FMTaction*> selected = node.source.targets(model.actions);
1818
1819 //Core::FMTaction optimization_action;
1820 for (const FMTvertex_descriptor& vertex : verticies)
1821 {
1822 const Core::FMTdevelopment& development = data[vertex].get();
1823 const Graph::FMTgraphvertextoyield vertexinfo = getvertextoyieldinfo(model,vertex);
1824 std::string value;
1825 if (level == Core::FMToutputlevel::standard)
1826 {
1827 value = development.getmask().get(theme);
1828 }
1829 else if (level == Core::FMToutputlevel::developpement)
1830 {
1831 if (node.source.isnextperiod())//If it looks at next period make sure to show the right dev...
1832 {
1833 value = std::string(data[getgrowthsource(vertex)].get());
1834 }else {
1835 value = std::string(development);
1836 }
1837
1838 values[value] = 0;
1839 }
1840 else {
1841 value = "Total";
1842 }
1843 if (node.source.useinedges())
1844 {
1845 Core::FMTdevelopment newdev(development);
1846 newdev.setperiod(newdev.getperiod() - 1);
1847 const double coef = node.source.getcoef(newdev, model.yields, &vertexinfo) * node.factor.getcoef(newdev, model.yields, &vertexinfo) * node.constant;
1848 double area = 0;
1849 if (development.getperiod() == 0)
1850 {
1851 area = outarea(vertex, -1, solution);
1852 }
1853 else {
1854 area = inarea(vertex, solution,-1,!node.source.isaction());
1855 }
1856 values[value] += coef * area;
1857 }
1858 else {
1859 for (const Core::FMTaction* act : selected)
1860 {
1861 double action_value = 0;
1862 const int actionID = static_cast<int>(std::distance(&(*model.actions.begin()), act));
1863 const std::vector<Core::FMTdevelopmentpath>paths = getpaths(vertex, actionID);
1864 const double action_coef = node.source.getcoef(development, model.yields, &vertexinfo,&paths,act) * node.factor.getcoef(development, model.yields, &vertexinfo,&paths,act) * node.constant;
1865 action_value = action_coef * (outarea(vertex, actionID, solution));
1866 values[value] += action_value;
1867 }
1868 }
1869
1870 }
1871 }
1872 if (level == Core::FMToutputlevel::standard)
1873 {
1874 double total = 0;
1875 for (auto valit : values)
1876 {
1877 total += valit.second;
1878 }
1879 values["Total"] = total;
1880 }
1881 }
1882 catch (...)
1883 {
1884 _exhandler->raisefromcatch("For node: "+std::string(node)+ " on theme "+std::string(theme), "FMTgraph::getvalues", __LINE__, __FILE__);
1885 }
1886 return values;
1887 }
1888 int getperiod() const
1889 {
1890 try {
1891 FMTvertex_iterator vertex, vend;
1892 boost::tie(vertex, vend) = vertices(data);
1893 --vend;
1894 return (data[*vend].get().getperiod());
1895 }catch (...)
1896 {
1897 _exhandler->raisefromcatch("", "FMTgraph::getperiod", __LINE__, __FILE__);
1898 }
1899 return 0;
1900 }
1901
1903 {
1904 try {
1905 for (size_t nodecacheid = 0; nodecacheid < nodescache.size(); ++nodecacheid)
1906 {
1907 nodescache[nodecacheid].rebase(developments.at(nodecacheid).first,developments.at(nodecacheid).second);
1908 }
1909 }
1910 catch (...)
1911 {
1912 _exhandler->raisefromcatch("", "FMTgraph::rebasecache", __LINE__, __FILE__);
1913 }
1914 }
1915
1916
1918 {
1919 try {
1920 nodescache.clear();
1921 developments.clear();
1922 FMTvertex_iterator base_iterator, base_iterator_end;
1923 //End always stay the same use .end() for non valid period
1924 boost::tie(base_iterator, base_iterator_end) = boost::vertices(data);
1925 if (base_iterator!= base_iterator_end)
1926 {
1927 developments.resize(getperiod() + 1, FMTvertex_pair(base_iterator_end, base_iterator_end));
1928 FMTvertex_iterator vertex, vend;
1929 int actualperiod = 0;
1930 size_t vertexid = 0;
1931 FMTvertex_iterator firstvertex;
1932 for (boost::tie(vertex, vend) = boost::vertices(data); vertex != vend; ++vertex)
1933 {
1934 const FMTbasevertexproperties& properties = data[*vertex];
1935 const Core::FMTdevelopment& dev = properties.get();
1936 const size_t period_location = (dev.getperiod());
1937 if (vertexid == 0)
1938 {
1939 firstvertex = vertex;
1940 actualperiod = dev.getperiod();
1941 }
1942 if (actualperiod != dev.getperiod())//periodchanges!
1943 {
1944 developments[period_location - 1] = FMTvertex_pair(firstvertex, vertex);
1945 firstvertex = vertex;
1946 actualperiod = dev.getperiod();
1947 }
1948 ++vertexid;
1949 }
1950 developments.back() = FMTvertex_pair(firstvertex, base_iterator_end);
1951 }
1952 }
1953 catch (...)
1954 {
1955 _exhandler->raisefromcatch("", "FMTgraph::generatedevelopments", __LINE__, __FILE__);
1956 }
1957 }
1958 bool sameedgesas(const FMTgraph& rhs) const
1959 {
1960 bool different = false;
1961 try {
1962 FMTedge_iterator thisedge_iterator, thisedge_iterator_end;
1963 FMTedge_iterator rhsedge_iterator, rhsedge_iterator_end;
1964 boost::tie(thisedge_iterator, thisedge_iterator_end) = boost::edges(data);
1965 boost::tie(rhsedge_iterator, rhsedge_iterator_end) = boost::edges(rhs.data);
1966 while (!different && thisedge_iterator != thisedge_iterator_end && rhsedge_iterator != rhsedge_iterator_end)
1967 {
1968 const FMTbaseedgeproperties& thisedgeprop = data[*thisedge_iterator];
1969 const FMTbaseedgeproperties& rhsedgeprop = rhs.data[*rhsedge_iterator];
1970 if (thisedgeprop.getactionID() != rhsedgeprop.getactionID())
1971 {
1972 different = true;
1973 }
1974 ++thisedge_iterator;
1975 ++rhsedge_iterator;
1976 }
1977 }catch (...)
1978 {
1979 _exhandler->raisefromcatch("", "FMTgraph::sameedgesas", __LINE__, __FILE__);
1980 }
1981 return different;
1982 }
1983 void updatematrixindex(const std::vector<int>& removedvariables,
1984 const std::vector<int>& removedconstraints)
1985 {
1986
1987 }
1989 {
1990 return static_cast<int>(std::distance(developments.begin(), getfirstconstblock()));
1991 }
1992
1993 FMTinedge_iterator getlastdisturbance(FMTinedge_iterator activeedge,int& periodtolastdisturbance) const
1994 {
1995 FMTinedge_iterator lastedge;
1996 try {
1997 std::queue<FMTinedge_iterator>actives;
1998 actives.push(activeedge);
1999 while (!actives.empty())
2000 {
2001 activeedge = actives.front();
2002 actives.pop();
2003 const FMTvertex_descriptor vertexsource = boost::source(*activeedge, data);
2004 if (data[*activeedge].getactionID() >= 0)
2005 {
2006 periodtolastdisturbance = data[vertexsource].get().getperiod();
2007 return activeedge;
2008 }
2009 FMTinedge_iterator inedge_iterator, inedge_end;
2010 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(vertexsource, data); inedge_iterator != inedge_end; ++inedge_iterator)
2011 {
2012 actives.push(inedge_iterator);
2013 }
2014 }
2015 lastedge = activeedge;
2016 }catch (...)
2017 {
2018 _exhandler->raisefromcatch("", "FMTgraph::getlastdisturbance", __LINE__, __FILE__);
2019 }
2020
2021 return lastedge;
2022 }
2023
2024 void filluplastactions(const int& targetperiod,const FMTvertex_descriptor& targetdescriptor,std::vector<const FMTbaseedgeproperties*>& lastactions, std::vector<int>& distances,const size_t& depth) const
2025 {
2026 try {
2027 std::queue<FMTvertex_descriptor>activevertex;
2028 activevertex.push(targetdescriptor);
2029 while (!activevertex.empty()&&lastactions.size() <= depth)
2030 {
2031 FMTvertex_descriptor descriptor = activevertex.front();
2032 activevertex.pop();
2033 FMTinedge_iterator inedge_iterator, inedge_end;
2034 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(descriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2035 {
2036 const FMTbaseedgeproperties& inedgeproperties = data[*inedge_iterator];
2037 const FMTvertex_descriptor& sourcevertex = boost::source(*inedge_iterator, data);
2038 activevertex.push(sourcevertex);
2039 const int sourceperiod = data[sourcevertex].get().getperiod();
2040 if (inedgeproperties.getactionID()>=0)
2041 {
2042 lastactions.push_back(&inedgeproperties);
2043 distances.push_back(targetperiod - sourceperiod);
2044 }
2045 if (sourceperiod == 0 && lastactions.size() <= depth)
2046 {
2047 lastactions.push_back(nullptr);
2048 distances.push_back(targetperiod-1 + data[sourcevertex].get().getage());//targetperiod-1 because distance between age20 at p1 and p2 == 21, not 22
2049 }
2050 }
2051 }
2052 }
2053 catch (...)
2054 {
2055 _exhandler->raisefromcatch("", "FMTgraph::filluplastactions", __LINE__, __FILE__);
2056 }
2057
2058 }
2059
2060
2061
2062 size_t getamountofpaths(const Core::FMTdevelopment& dev, const int& actionid,const Models::FMTmodel& model,
2063 const boost::unordered_set<Core::FMTlookup<FMTvertex_descriptor, Core::FMTdevelopment>>& actualperioddevs) const
2064 {
2065 size_t amount = 0;
2066 try {
2067 std::vector<FMTvertex_descriptor>paths;
2068 if (actionid >= 0)
2069 {
2070 for (const Core::FMTdevelopmentpath& path : dev.operate(model.actions.at(actionid), model.transitions.at(actionid), model.yields, model.themes))
2071 {
2072 if (containsdevelopment(*path.development, actualperioddevs))
2073 {
2074 paths.push_back(getdevelopment(*path.development, actualperioddevs));
2075 }
2076 }
2077 }
2078 else {
2079 const FMTvertex_descriptor& act = getdevelopment(dev, actualperioddevs);
2080 FMToutedge_pair edge_pair;
2081 for (edge_pair = boost::out_edges(act, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
2082 {
2083 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
2084 if (edgeprop.getactionID() < 0)
2085 {
2086 paths.push_back(boost::target(*edge_pair.first, data));
2087 break;
2088 }
2089 }
2090
2091 }
2092 for (const FMTvertex_descriptor& path : paths)
2093 {
2094 int period = getdevelopment(path).getperiod();
2095 FMTvertex_descriptor vdescriptor = path;
2096 while (period < size())
2097 {
2098 std::map<int, int>vars = getoutvariables(vdescriptor);
2099 vars.erase(-1);
2100 amount += vars.size();
2101 FMToutedge_pair edge_pair;
2102 bool gotit = false;
2103 for (edge_pair = boost::out_edges(vdescriptor, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
2104 {
2105 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
2106 if (edgeprop.getactionID() < 0)
2107 {
2108 vdescriptor = boost::target(*edge_pair.first, data);
2109 gotit = true;
2110 break;
2111 }
2112 }
2113 if (!gotit)
2114 {
2115 break;
2116 }
2117 ++period;
2118 }
2119 }
2120 }
2121 catch (...)
2122 {
2123 _exhandler->printexceptions("for " + std::string(dev), "FMTgraph::getamountofpaths", __LINE__, __FILE__);
2124 }
2125 return amount;
2126 }
2127 std::vector<Core::FMTaction>::const_iterator getactionoffirstserie(const FMTvertex_descriptor& targetdescriptor,
2128 std::vector<Core::FMTaction>::const_iterator theaction,
2129 const size_t& seriemaxsize, const std::vector<Core::FMTaction>& actions) const
2130 {
2131 try {
2132 int minperiod = 0;
2133 const std::vector<std::string> targetserie = getactionserie(targetdescriptor, seriemaxsize, actions);
2134 for (std::vector<Core::FMTaction>::const_iterator acit = theaction;acit!= actions.cend();++acit)
2135 {
2136 if (acit->ispartofaserie()&& acit->isallowedinserie(targetserie))
2137 {
2138 return acit;
2139 }
2140 }
2141 }
2142 catch (...)
2143 {
2144 _exhandler->printexceptions("", "FMTgraph::getactionserie", __LINE__, __FILE__);
2145 }
2146 return actions.cend();
2147 }
2148
2149 bool keepforserie(const FMTvertex_descriptor& targetdescriptor,
2150 std::vector<Core::FMTaction>::const_iterator theaction,
2151 const size_t& seriemaxsize,
2152 const std::vector<Core::FMTaction>& actions,
2153 bool& onserie) const
2154 {
2155 try {
2156 std::vector<Core::FMTaction>::const_iterator acit = getactionoffirstserie(targetdescriptor, theaction, seriemaxsize,actions);
2157 if (acit == actions.end())
2158 {
2159 onserie = false;
2160 }
2161 else if (acit == theaction)
2162 {
2163 onserie = true;
2164 }
2165 else {
2166 return true;
2167 //new_actives.push(front_vertex);
2168 //continue;
2169 }
2170 }
2171 catch (...)
2172 {
2173 _exhandler->printexceptions("", "FMTgraph::keepforserie", __LINE__, __FILE__);
2174 }
2175 return false;
2176 }
2177
2178
2179 std::vector<std::string> getactionserie(FMTvertex_descriptor targetdescriptor,
2180 const size_t& maxactions, const std::vector<Core::FMTaction>& actions) const
2181
2182 {
2183 std::vector<std::string>theserie;
2184 try {
2185 size_t inedgessize = boost::in_degree(targetdescriptor,data);
2186 while (inedgessize>0 && theserie.size()<maxactions)
2187 {
2188 if (inedgessize > 0)
2189 {
2190 if (inedgessize > 1)
2191 {
2192 FMTinedge_iterator inedge_iterator, inedge_end;
2193 std::string actions;
2194 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(targetdescriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2195 {
2196 const FMTbaseedgeproperties& inedgeproperties = data[*inedge_iterator];
2197 actions += std::to_string(inedgeproperties.getactionID())+" ";
2198 }
2199 const FMTbasevertexproperties& targetproperties = data[targetdescriptor];
2200 _exhandler->raise(Exception::FMTexc::FMTrangeerror,
2201 "Developement " + std::string(targetproperties.get()) + " has " + std::to_string(inedgessize) + " in edges ("+actions+")",
2202 "FMTgraph::getactionserie", __LINE__, __FILE__);
2203 }
2204 FMTinedge_iterator inedge_iterator, inedge_end;
2205 boost::tie(inedge_iterator, inedge_end) = boost::in_edges(targetdescriptor, data);
2206 const FMTbaseedgeproperties& inedgeproperties = data[*inedge_iterator];
2207 const int actionid = inedgeproperties.getactionID();
2208 if (actionid >=0)
2209 {
2210 theserie.insert(theserie.begin(), actions.at(actionid).getname());
2211 }
2212 targetdescriptor = boost::source(*inedge_iterator, data);
2213 inedgessize = boost::in_degree(targetdescriptor, data);
2214 }
2215 }
2216 }catch (...)
2217 {
2218 _exhandler->printexceptions("", "FMTgraph::getactionserie", __LINE__, __FILE__);
2219 }
2220 return theserie;
2221 }
2222
2223 std::set<Core::FMTSerie>getallseries(FMTvertex_descriptor targetdescriptor,const std::string& seriestarter,const std::vector<Core::FMTaction>& actions, const std::unordered_set<int>& actionselected,const Core::FMTmask& mask) const
2224
2225 {
2226 std::set<Core::FMTSerie>theseries;
2227 try {
2228 size_t inedgessize = boost::in_degree(targetdescriptor, data);
2229 const FMTbasevertexproperties& mainproperties = data[targetdescriptor];
2230 const int startperiod = mainproperties.get().getperiod();
2231 std::string actualserie(seriestarter);
2232 //The actual serie end up with the out_degree...
2233 //*_logger <<"in "<< std::string(mainproperties.get())<<" in degree "<< inedgessize << "\n";
2234 while (inedgessize > 0)
2235 {
2236 FMTinedge_iterator inedge_iterator, inedge_end;
2237 if (inedgessize>1)
2238 {
2239 inedgessize = 0;
2240 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(targetdescriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2241 {
2242 std::string subserie(actualserie);
2243 FMTvertex_descriptor subdescriptor = boost::source(*inedge_iterator, data);
2244 const FMTbasevertexproperties& targetproperties = data[subdescriptor];
2245 if (targetproperties.get().getmask().issubsetof(mask))//natural growth or action in the aggregate
2246 {
2247 const FMTbaseedgeproperties& inedgeproperties = data[*inedge_iterator];
2248 const int actionid = inedgeproperties.getactionID();
2249 const int perioddiff = startperiod - targetproperties.get().getperiod();
2250 //bool digMore = true;
2251 if (/*actionid >= 0 &&*/ actionselected.find(actionid) != actionselected.end())
2252 {
2253 //if ()
2254 //{
2255 subserie = actions.at(actionid).getname() + "-" + subserie;
2256 theseries.insert(Core::FMTSerie(subserie, perioddiff));//Always add the subserie
2257 //}else {
2258 // digMore = false;
2259 //}
2260
2261 }
2262 //if (digMore)
2263 //{
2264 for (const Core::FMTSerie& subofserie : getallseries(subdescriptor, subserie, actions, actionselected, mask))
2265 {
2266 //const std::string fullserie = subofserie.first +"-" + subserie;
2267 const int perioddepth = subofserie.getLength() + perioddiff;
2268 theseries.insert(Core::FMTSerie(subofserie.getSerie(), perioddepth));
2269 }
2270 //}
2271
2272 }
2273 }
2274
2275 } else {
2276 inedgessize = 0;
2277 boost::tie(inedge_iterator, inedge_end) = boost::in_edges(targetdescriptor, data);
2278 if (inedge_iterator != inedge_end)
2279 {
2280 targetdescriptor = boost::source(*inedge_iterator, data);
2281 const FMTbasevertexproperties& targetproperties = data[targetdescriptor];
2282 //*_logger << "in for out " << std::string(targetproperties.get()) << " in degree " << inedgessize << "\n";
2283 if (targetproperties.get().getmask().issubsetof(mask))//natural growth or action in the aggregate
2284 {
2285 const FMTbaseedgeproperties& inedgeproperties = data[*inedge_iterator];
2286 const int actionid = inedgeproperties.getactionID();
2287 if (/*actionid >= 0 &&*/ actionselected.find(actionid) != actionselected.end())
2288 {
2289 actualserie = actions.at(actionid).getname() + "-" + actualserie;
2290 theseries.insert(Core::FMTSerie(actualserie, startperiod - targetproperties.get().getperiod()));//Always add the subserie
2291 }
2292 inedgessize = boost::in_degree(targetdescriptor, data);
2293 }
2294 }
2295 }
2296
2297 }
2298 }
2299 catch (...)
2300 {
2301 _exhandler->printexceptions("", "FMTgraph::getallseries", __LINE__, __FILE__);
2302 }
2303 return theseries;
2304 }
2305
2306 size_t timesincelastaction(const FMTvertex_descriptor& targetdescriptor) const
2307 {
2308 try {
2309 std::queue<std::pair<FMTvertex_descriptor,size_t>>verticies_n_depth;
2310 verticies_n_depth.push(std::pair<FMTvertex_descriptor, size_t>(targetdescriptor, 0));
2311 while (!verticies_n_depth.empty())
2312 {
2313 const std::pair<FMTvertex_descriptor, size_t> descriptor_n_depth = verticies_n_depth.front();
2314 FMTinedge_iterator inedge_iterator, inedge_end;
2315 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(descriptor_n_depth.first, data); inedge_iterator != inedge_end; ++inedge_iterator)
2316 {
2317 const FMTbaseedgeproperties& edgeprop = data[*inedge_iterator];
2318 if (edgeprop.getactionID() != -1)
2319 {
2320 return descriptor_n_depth.second;
2321 }else{
2322 const FMTvertex_descriptor sourcevertex = boost::source(*inedge_iterator, data);
2323 verticies_n_depth.push(std::pair<FMTvertex_descriptor, size_t>(sourcevertex,descriptor_n_depth.second+1));
2324 }
2325 }
2326 verticies_n_depth.pop();
2327 }
2328
2329 }catch (...)
2330 {
2331 _exhandler->raisefromcatch("", "FMTgraph::timesincelastaction", __LINE__, __FILE__);
2332 }
2333 return std::numeric_limits<size_t>::max();
2334 }
2335
2336
2337 std::vector<FMTpredictor> getpredictors(const FMTvertex_descriptor& targetdescriptor,const Models::FMTmodel& model,
2338 const std::vector<std::string>& yieldnames,const size_t& depth,bool periodonevalues= false, bool withGCBMid =true) const
2339 {
2340 std::vector<FMTpredictor> predictors;
2341 try {
2342 FMTinedge_iterator inedge_iterator, inedge_end;
2343 const FMTbasevertexproperties& targetproperties = data[targetdescriptor];
2344 const int targetperiod = targetproperties.get().getperiod();
2345 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(targetdescriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2346 {
2347 std::vector<const FMTbaseedgeproperties*>lastactions;
2348 std::vector<int>distances;
2349 const FMTvertex_descriptor& sourcevertex = boost::source(*inedge_iterator, data);
2350 const FMTbasevertexproperties& sourceproperties = data[sourcevertex];
2351 const int sourceperiod = sourceproperties.get().getperiod();
2352 if (sourceperiod>0||periodonevalues)
2353 {
2354 lastactions.push_back(&data[*inedge_iterator]);
2355 distances.push_back(targetperiod-sourceperiod);
2356 }else{
2357 break;//if nothing happen in period one, it's not a predictor, because there is no change in yields and other things because P0 = begining of P1
2358 }
2359 filluplastactions(targetperiod, sourcevertex, lastactions, distances, depth);
2360 while (lastactions.size()<= depth)
2361 {
2362 lastactions.push_back(nullptr);
2363 distances.push_back(-1);
2364 }
2365 predictors.emplace_back(model.actions, yieldnames,model.yields, sourceproperties, targetproperties, lastactions, distances,withGCBMid);
2366 }
2367 predictors.shrink_to_fit();
2368 }catch (...)
2369 {
2370 _exhandler->raisefromcatch("", "FMTgraph::getpredictors", __LINE__, __FILE__);
2371 }
2372 return predictors;
2373 }
2374
2375 int getfirstperiod() const
2376 {
2377 return data[*developments.at(getfirstactiveperiod() + 1).first].get().getperiod();
2378 }
2379 void postsolve(const Core::FMTmaskfilter& filter,
2380 const std::vector<Core::FMTtheme>&originalbasethemes,
2381 const std::vector<int>& actionmapconnection)
2382 {
2383 try {
2384 developments.clear();
2385 nodescache.clear();//Some postsolve can be done here to keep some usefull information but for now just clear
2386 //start by remapping the actions
2387 FMTedge_iterator edge_iterator, edge_iterator_end;
2388 for (boost::tie(edge_iterator, edge_iterator_end) = boost::edges(data); edge_iterator != edge_iterator_end; ++edge_iterator)
2389 {
2390 FMTbaseedgeproperties& edgeprop = data[*edge_iterator];
2391 if (edgeprop.getactionID()>=0)
2392 {
2393 edgeprop.setactionID(actionmapconnection.at(edgeprop.getactionID()));
2394 }
2395 }
2396 boost::unordered_map<Core::FMTmask,Core::FMTmask>presolvetopostsolve;
2397 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
2398 for (boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
2399 {
2400 FMTbasevertexproperties& vertexprop = data[*vertex_iterator];
2401 const Core::FMTmask& presolvemask = vertexprop.get().getmask();
2402 boost::unordered_map<Core::FMTmask, Core::FMTmask>::const_iterator mskit = presolvetopostsolve.find(presolvemask);
2403 if (mskit != presolvetopostsolve.end())
2404 {
2405 vertexprop.setdevlopementmask(mskit->second);
2406 }else {
2407 const Core::FMTmask postsolvedmask = presolvemask.postsolve(filter, originalbasethemes);
2408 presolvetopostsolve[presolvemask] = postsolvedmask;
2409 vertexprop.setdevlopementmask(postsolvedmask);
2410 }
2411 }
2412 generatedevelopments();
2413 }
2414 catch (...)
2415 {
2416 _exhandler->raisefromcatch("", "FMTgraph::postsolve", __LINE__, __FILE__);
2417 }
2418 }
2419 Core::FMTschedule getschedule(const std::vector<Core::FMTaction>& actions, const double* actual_solution, const int& lperiod,bool withlock = false) const
2420 {
2421 Core::FMTschedule newschedule(lperiod,*this, withlock);
2422 try {
2423 if (static_cast<int>(size()) > lperiod && lperiod > 0)
2424 {
2425 //newschedule.setperiod(lperiod);
2426 //std::map<Core::FMTaction, std::map<Core::FMTdevelopment, std::map<int, double>>>schedule_solution;
2427 //const double* actual_solution = this->getColSolution();
2428 FMTvertex_iterator vertex_iterator,vertex_iterator_end;
2429 for (boost::tie(vertex_iterator, vertex_iterator_end) = getperiodverticies(lperiod); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
2430 {
2431 const FMTvertex_descriptor vertex = *vertex_iterator;
2432 std::map<int, int>variables = getoutvariables(vertex);
2433 variables.erase(-1);
2434 if (!variables.empty())
2435 {
2436 const Core::FMTdevelopment& dev = data[*vertex_iterator].get();
2437 for (const auto variable_iterator : variables)
2438 {
2439 if (*(actual_solution + variable_iterator.second) > FMT_DBL_TOLERANCE) //basis solution only!!!
2440 {
2441
2442 /*if (schedule_solution.find(actions[variable_iterator.first]) == schedule_solution.end())
2443 {
2444 schedule_solution[actions[variable_iterator.first]] = std::map<Core::FMTdevelopment, std::map<int, double>>();
2445 }
2446 const Core::FMTdevelopment& basedev = getdevelopment(deviterator.memoryobject);*/
2447 newschedule.addevent(dev, *(actual_solution + variable_iterator.second), actions.at(variable_iterator.first));
2448 /*Core::FMTdevelopment lockout = basedev.clearlock();
2449 int leveltarget = basedev.lock;
2450 if (withlock)
2451 {
2452 lockout = basedev;
2453 leveltarget = 0;
2454 }
2455 if (schedule_solution[actions[variable_iterator.first]].find(lockout) == schedule_solution[actions[variable_iterator.first]].end())
2456 {
2457 schedule_solution[actions[variable_iterator.first]][lockout] = std::map<int, double>();
2458 }
2459 schedule_solution[actions[variable_iterator.first]][lockout][leveltarget] = (*(actual_solution + variable_iterator.second));*/
2460 }
2461 }
2462
2463 }
2464 }
2465 newschedule.clean();
2466 /*Core::FMTschedule newschedule(lperiod, schedule_solution);
2467 newschedule.passinobject(*this);
2468 if (withlock)
2469 {
2470 newschedule.setuselock(true);
2471 }*/
2472 //return newschedule;
2473 }
2474 }
2475 catch (...)
2476 {
2477 _exhandler->raisefromcatch("at period " + std::to_string(lperiod), "FMTgraph::getschedule", __LINE__, __FILE__);
2478 }
2479
2480 return newschedule;
2481 }
2482 // DocString: FMTgraph::getrorations
2492 std::set<Core::FMTSerie>getrorations(const Models::FMTmodel& model,const Core::FMTmask& mask,const std::string& aggregate) const
2493 {
2494 std::set<Core::FMTSerie>theseries;
2495 try {
2496 const Core::FMToutputsource basesource(Core::FMTspec(), mask,
2497 Core::FMTotar::actual,"", aggregate);
2498 const Core::FMToutputsource basefactor(Core::FMTotar::val, 1.0);
2499 const Core::FMToutputnode basenode(basesource, basefactor, 1.0);
2500 const int minperiod = 1;
2501 const int maxperiod = static_cast<int>(developments.size() - 2);
2502 const std::unordered_set<int> actionsets = Core::FMTactioncomparator(aggregate).getallaggregatesset(model.actions, true);
2503 for (int period = minperiod; period <= maxperiod;++period)
2504 {
2505 Core::FMToutputnode periodnode(basenode);
2506 for (const FMTvertex_descriptor& targetdescriptor : getnode(model, periodnode, period))
2507 {
2508 FMToutedge_pair edge_pair;
2509 for (edge_pair = boost::out_edges(targetdescriptor, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
2510 {
2511 const FMTbaseedgeproperties& edgeprop = data[*edge_pair.first];
2512 int actionid = edgeprop.getactionID();
2513 if (/*actionid >= 0 &&*/ actionsets.find(actionid) != actionsets.end())
2514 {
2515 const std::string startup = model.actions.at(actionid).getname();
2516 std::set<Core::FMTSerie>subset;
2517 const std::set<Core::FMTSerie>periodseries = getallseries(targetdescriptor,startup,model.actions, actionsets, mask);
2518 if (!periodseries.empty())
2519 {
2520 std::set_union(periodseries.begin(), periodseries.end(),
2521 theseries.begin(), theseries.end(),
2522 std::inserter(subset, std::begin(subset)));
2523 theseries.swap(subset);
2524 }
2525
2526 }
2527 }
2528
2529
2530 }
2531 }
2532 }catch (...)
2533 {
2534 _exhandler->raisefromcatch("", "FMTgraph::getrorations", __LINE__, __FILE__);
2535 }
2536 return theseries;
2537 }
2538
2539
2540 Core::FMTschedule getoutvariablesproportions(const std::vector<Core::FMTaction>& actions, const double* actual_solution, const int& lperiod,bool withlock = false) const
2541 {
2542 Core::FMTschedule newschedule(lperiod,*this, withlock);
2543 try {
2544 if (static_cast<int>(size()) > lperiod && lperiod > 0)
2545 {
2546 FMTvertex_iterator vertex_iterator,vertex_iterator_end;
2547 for (boost::tie(vertex_iterator, vertex_iterator_end) = getperiodverticies(lperiod); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
2548 {
2549 const FMTvertex_descriptor vertex = *vertex_iterator;
2550 std::map<int, int>variables = getoutvariables(vertex);
2551 const Core::FMTdevelopment& dev = data[*vertex_iterator].get();
2552 double outarea = 0;
2553 std::map<int,double>variablesarea;
2554 for (const auto variable_iterator : variables)
2555 {
2556 const double vout = *(actual_solution + variable_iterator.second);
2557 /*if(vout>0)
2558 {
2559 std::cout<<std::string(dev)+" Variable : "+std::to_string(variable_iterator.first)+" Outarea : "+std::to_string(vout)<<std::endl;
2560 }*/
2561 if (vout > FMT_DBL_TOLERANCE) //basis solution only!!!
2562 {
2563 if(variable_iterator.first>=0)
2564 {
2565 variablesarea[variable_iterator.first]=vout;
2566 }
2567 outarea+=vout;
2568 }
2569 }
2570 //std::cout<<"Total area : "+std::to_string(outarea)<<std::endl;
2571 for (const auto variable_iterator : variablesarea)
2572 {
2573 newschedule.addevent(dev, variable_iterator.second/outarea, actions.at(variable_iterator.first));
2574 //std::cout<<std::string(dev)+" Variable : "+std::to_string(variable_iterator.first)+" Proportion : "+std::to_string(variable_iterator.second/outarea)<<std::endl;
2575 }
2576 }
2577 newschedule.clean();
2578 }
2579 }
2580 catch (...)
2581 {
2582 _exhandler->raisefromcatch("at period " + std::to_string(lperiod), "FMTgraph::getproportionsschedule", __LINE__, __FILE__);
2583 }
2584
2585 return newschedule;
2586 }
2587 operator std::string() const
2588 {
2589 std::ostringstream stream;
2590 try {
2591 //write_graphviz(stream, data);
2592 }catch (...)
2593 {
2594 _exhandler->raisefromcatch("", "FMTgraph::std::string()", __LINE__, __FILE__);
2595 }
2596 return stream.str();
2597 }
2598
2599 };
2600
2601
2603 {
2604 std::map<int, int> mapping;
2605 try {
2606 FMToutedge_pair edge_pair;
2607 for (edge_pair = boost::out_edges(out_vertex, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
2608 {
2609 const FMTedgeproperties& edgeprop = data[*edge_pair.first];
2610 int actionid = edgeprop.getactionID();
2611 mapping[actionid] = edgeprop.getvariableID();
2612 }
2613 }catch (...)
2614 {
2615 _exhandler->raisefromcatch("", "FMTgraph::getoutvariables", __LINE__, __FILE__);
2616 }
2617 return mapping;
2618 }
2619
2620
2621
2622
2623template<> inline std::vector<Core::FMTdevelopmentpath> FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>::getpaths(const FMTvertex_descriptor& out_vertex, const int& actionID) const
2624 {
2625 std::vector<Core::FMTdevelopmentpath>paths;
2626 try {
2627 for (FMToutedge_pair edge_pair = boost::out_edges(out_vertex, data); edge_pair.first != edge_pair.second; ++edge_pair.first)
2628 {
2629 const FMTedgeproperties& edgeprop = data[*edge_pair.first];
2630 if (edgeprop.getactionID() == actionID)
2631 {
2632 const FMTbasevertexproperties& vertex_target = data[target(*edge_pair.first, data)];
2633 paths.push_back(Core::FMTdevelopmentpath(vertex_target.get(), edgeprop.getproportion()));
2634 }
2635 }
2636 }catch (...)
2637 {
2638 _exhandler->raisefromcatch("", "FMTgraph::getpaths", __LINE__, __FILE__);
2639 }
2640 return paths;
2641 }
2642
2643
2644
2645template<> inline double FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>::inarea(const FMTvertex_descriptor& out_vertex, const double*& solution, int actionid , bool growth) const
2646 {
2647
2648 double area = 0;
2649 try {
2650 FMTinedge_iterator inedge_iterator, inedge_end;
2651 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(out_vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
2652 {
2653 const FMTedgeproperties& edgeprop = data[*inedge_iterator];
2654 if (edgeprop.getactionID() == actionid || !growth)
2655 {
2656 area += *(solution + edgeprop.getvariableID()) * (edgeprop.getproportion() / 100);
2657 }
2658 }
2659 }catch (...)
2660 {
2661 _exhandler->raisefromcatch("", "FMTgraph::inarea", __LINE__, __FILE__);
2662 }
2663 return area;
2664 }
2665
2666template<> inline double FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>::outarea(const FMTvertex_descriptor& out_vertex, const int& actionID, const double*& solution) const
2667 {
2668 double value = 0;
2669 FMToutedge_iterator outedge_iterator, outedge_end;
2670 try {
2671 for (boost::tie(outedge_iterator, outedge_end) = boost::out_edges(out_vertex, data); outedge_iterator != outedge_end; ++outedge_iterator)
2672 {
2673 const FMTedgeproperties& edgeprop = data[*outedge_iterator];
2674 if (edgeprop.getactionID() == actionID)
2675 {
2676 value += *(solution + edgeprop.getvariableID()) * (edgeprop.getproportion() / 100);
2677 }
2678 }
2679 }catch (...)
2680 {
2681 _exhandler->raisefromcatch("", "FMTgraph::outarea", __LINE__, __FILE__);
2682 }
2683 return value;
2684
2685 }
2686
2687template<> inline std::map<int, double> FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>::getvariables(const Models::FMTmodel& model, const Core::FMToutputnode& output_node, const std::vector<FMTvertex_descriptor>& verticies) const
2688{
2689 std::map<int, double>variables;
2690 try {
2691 if (!verticies.empty())
2692 {
2693 //std::vector<Core::FMTdevelopmentpath>paths;
2694 //Core::FMTaction optimization_action;
2695 const std::vector<const Core::FMTaction*> selected = output_node.source.targets(model.actions);
2696 for (const FMTvertex_descriptor& vertex : verticies)
2697 {
2698 const Core::FMTdevelopment& development = data[vertex].get();
2699 const Graph::FMTgraphvertextoyield vertexinfo = getvertextoyieldinfo(model,vertex);
2700 if (output_node.source.useinedges())
2701 {
2702
2703 Core::FMTdevelopment newdev(development);
2704 newdev.setperiod(newdev.getperiod() - 1);
2705 const double coef = output_node.source.getcoef(newdev, model.yields, &vertexinfo) * output_node.factor.getcoef(newdev, model.yields, &vertexinfo) * output_node.constant;
2706
2707 if (development.getperiod() == 0)
2708 {
2709 const std::map<int, int>vars = getoutvariables(vertex);
2710 updatevarsmap(variables, vars.at(-1), coef);
2711 }
2712 else {
2713 FMTinedge_iterator inedge_iterator, inedge_end;
2714 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(vertex, data); inedge_iterator != inedge_end; ++inedge_iterator)
2715 {
2716 const FMTedgeproperties& edgeprop = data[*inedge_iterator];
2717 const int actionid = edgeprop.getactionID();
2718 if (actionid < 0 || output_node.source.isaction())
2719 {
2720 updatevarsmap(variables, edgeprop.getvariableID(), (edgeprop.getproportion() / 100)*coef);
2721 continue;
2722 }
2723 const FMTvertex_descriptor sourceverex = boost::source(*inedge_iterator, data);
2724 const FMTvertexproperties& sourceproperties = data[sourceverex];
2725 if ((sourceproperties.get().getperiod() == development.getperiod() && !periodstart(sourceverex)))
2726 {
2727 updatevarsmap(variables, edgeprop.getvariableID(), (edgeprop.getproportion() / 100)*coef);
2728 }
2729 }
2730 }
2731
2732 }
2733 else {
2734 const std::map<int, int>outvars = getoutvariables(vertex);
2735 for (const Core::FMTaction* act : selected)
2736 {
2737 const int actionID = static_cast<int>(std::distance(&(*model.actions.begin()), act));
2738 if (outvars.find(actionID) != outvars.end())
2739 {
2740 const std::vector<Core::FMTdevelopmentpath>paths = getpaths(vertex, actionID);
2741 const double action_coef = output_node.source.getcoef(development, model.yields, &vertexinfo, &paths, act) * output_node.factor.getcoef(development, model.yields, &vertexinfo, &paths, act) * output_node.constant;
2742 updatevarsmap(variables, outvars.at(actionID), action_coef);
2743 }
2744 }
2745 }
2746 }
2747 }
2748 }
2749 catch (...)
2750 {
2751 _exhandler->raisefromcatch("", "FMTgraph::getvariables", __LINE__, __FILE__);
2752 }
2753 return variables;
2754}
2755
2757 std::vector<int>&deletedvariables,
2758 bool keepbounded)
2759{
2760 try {
2761 typename std::vector<FMTvertex_pair>::iterator periodit = this->getfirstblock();
2762 FMTvertex_iterator vertexit, vertexend;
2763 for (boost::tie(vertexit, vertexend) = *periodit; vertexit != vertexend; ++vertexit)
2764 {
2765 const FMTvertex_descriptor& vertex_location = *vertexit;
2766 FMTinedge_iterator inedge_iterator, inedge_end;
2767 bool gotinedges = false;
2768 const bool nottransferrow = isnotransfer(vertex_location, 1);
2769
2770 if (!nottransferrow)
2771 {
2772 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(vertex_location, data); inedge_iterator != inedge_end; ++inedge_iterator)
2773 {
2774 gotinedges = true;
2775 const FMTedgeproperties& edgeproperty = data[*inedge_iterator];
2776 int varvalue = edgeproperty.getvariableID();
2777 if (std::find(deletedvariables.begin(), deletedvariables.end(), varvalue) == deletedvariables.end())
2778 {
2779 --stats.cols;
2780 deletedvariables.push_back(varvalue);
2781 }
2782 --stats.edges;
2783 }
2784 }
2785
2786 if (!keepbounded)
2787 {
2788 if (!nottransferrow)
2789 {
2790 const std::map<int, int>outvars = this->getoutvariables(vertex_location);
2791 for (std::map<int, int>::const_iterator varit = outvars.begin(); varit != outvars.end(); varit++)
2792 {
2793 if (std::find(deletedvariables.begin(), deletedvariables.end(), varit->second) == deletedvariables.end())
2794 {
2795 --stats.cols;
2796 deletedvariables.push_back(varit->second);
2797 }
2798 --stats.edges;
2799 }
2800 }
2801 boost::clear_out_edges(vertex_location, data);
2802 }
2803 boost::clear_in_edges(vertex_location, data);
2804 }
2805 FMTvertex_iterator firstvertex;
2806 FMTvertex_iterator lastvertex;
2807 bool assigned = false;
2808 for (boost::tie(vertexit, vertexend) = *periodit; vertexit != vertexend; ++vertexit)
2809 {
2810 const FMTvertex_descriptor& vertex_location = *vertexit;
2811 FMTvertexproperties& vertexproperty = data[vertex_location];
2812 const int constvalue = vertexproperty.getconstraintID();
2813 if (constvalue >= 0)
2814 {
2815 --stats.rows;
2816 --stats.transfer_rows;
2817 deletedconstraints.push_back(constvalue);
2818 vertexproperty.setconstraintID(-1);
2819 }
2820 if (!keepbounded || out_degree(vertex_location, data) == 0)
2821 {
2822 boost::remove_vertex(vertex_location, data);
2823 --stats.vertices;
2824 }
2825 else if (!assigned)
2826 {
2827 firstvertex = vertexit;
2828 lastvertex = vertexit;
2829 assigned = true;
2830 }
2831 else {
2832 lastvertex = vertexit;
2833 }
2834 }
2835 ++lastvertex;
2836 *periodit = FMTvertex_pair(firstvertex, lastvertex);
2837 rebasecache();
2838 const int firstperiod = this->getfirstactiveperiod();
2839 /*if (static_cast<size_t>(firstperiod) < nodescache.size())
2840 {
2841 nodescache[firstperiod].clear();
2842 }*/
2843 nodescache.clear();
2844
2845 }
2846 catch (...)
2847 {
2848 _exhandler->raisefromcatch("", "FMTgraph::eraseperiod", __LINE__, __FILE__);
2849 }
2850 return stats;
2851}
2852
2854{
2855 data[vertex].setconstraintID(id);
2856}
2857
2859 std::vector<int>&row_starts,
2860 std::vector<int>& cols,
2861 std::vector<double>& cols_value) const
2862{
2863 try {
2864 FMTinedge_iterator inedge_iterator, inedge_end;
2865 FMTvertexproperties vertex_property = data[vertex_descriptor];
2866 row_starts.push_back(static_cast<int>(cols.size()));
2867 bool gotin = false;
2868 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(vertex_descriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2869 {
2870 const FMTedgeproperties& edgeprop = data[*inedge_iterator];
2871 cols.push_back(edgeprop.getvariableID());
2872 cols_value.push_back((edgeprop.getproportion() / 100));
2873 gotin = true;
2874 }
2875 std::vector<int>locals;
2876 FMToutedge_iterator outedge_iterator, outedge_end;
2877 for (boost::tie(outedge_iterator, outedge_end) = boost::out_edges(vertex_descriptor, data); outedge_iterator != outedge_end; ++outedge_iterator)
2878 {
2879 const FMTedgeproperties& edgeprop = data[*outedge_iterator];
2880 const int edgevar = edgeprop.getvariableID();
2881 if (std::find(locals.begin(), locals.end(), edgevar) == locals.end())
2882 {
2883 cols.push_back(edgevar);
2884 locals.push_back(edgevar);
2885 cols_value.push_back(-1);
2886 }
2887 }
2888 if (!gotin)
2889 {
2890 const Core::FMTdevelopment& dev = vertex_property.get();
2891 _exhandler->raise(Exception::FMTexc::FMTrangeerror,
2892 "No in variables for development "+std::string(dev), "FMTgraph::gettransferrow", __LINE__, __FILE__);
2893 }
2894 }
2895 catch (...)
2896 {
2897 _exhandler->raisefromcatch("", "FMTgraph::gettransferrow", __LINE__, __FILE__);
2898 }
2899 return true;
2900}
2901
2903{
2904 try {
2905 FMTinedge_iterator inedge_iterator, inedge_end;
2906 FMTvertexproperties vertex_property = data[vertex_descriptor];
2907 for (boost::tie(inedge_iterator, inedge_end) = boost::in_edges(vertex_descriptor, data); inedge_iterator != inedge_end; ++inedge_iterator)
2908 {
2909 const FMTedgeproperties& edgeprop = data[*inedge_iterator];
2910 return edgeprop.getproportion();
2911 }
2912 }
2913 catch (...)
2914 {
2915 _exhandler->raisefromcatch("", "FMTgraph::getinproportion", __LINE__, __FILE__);
2916 }
2917 return 1;
2918}
2919
2920
2921
2923 const std::vector<int>& removedvariables,
2924 const std::vector<int>& removedconstraints)
2925{
2926 try {
2927 if (!removedconstraints.empty())
2928 {
2929 const int& maxconstraint = removedconstraints.back();
2930 const int& minconstraint = removedconstraints.front();
2931 FMTvertex_iterator vertex_iterator, vertex_iterator_end;
2932 for (boost::tie(vertex_iterator, vertex_iterator_end) = boost::vertices(data); vertex_iterator != vertex_iterator_end; ++vertex_iterator)
2933 {
2934 FMTvertexproperties& vertexproperty = data[*vertex_iterator];
2935 const int actualconstraint = vertexproperty.getconstraintID();
2936 if (actualconstraint >= 0)
2937 {
2938 int toremove = 0;
2939 if (actualconstraint > minconstraint && actualconstraint < maxconstraint)
2940 {
2941 std::vector<int>::const_iterator removeditconstraint = removedconstraints.begin();
2942 while (removeditconstraint != removedconstraints.end() && actualconstraint > *removeditconstraint)
2943 {
2944 ++toremove;
2945 ++removeditconstraint;
2946 }
2947 }
2948 else if (actualconstraint > maxconstraint)
2949 {
2950 toremove = static_cast<int>(removedconstraints.size());
2951 }
2952 vertexproperty.setconstraintID(actualconstraint - toremove);
2953 }
2954 }
2955 }
2956
2957 if (!removedvariables.empty())
2958 {
2959 const int& maxvariable = removedvariables.back();
2960 const int& minvariable = removedvariables.front();
2961 FMTedge_iterator edge_iterator, edge_iterator_end;
2962 for (boost::tie(edge_iterator, edge_iterator_end) = boost::edges(data); edge_iterator != edge_iterator_end; ++edge_iterator)
2963 {
2964 FMTedgeproperties& edgeproperty = data[*edge_iterator];
2965 const int actualvariable = edgeproperty.getvariableID();
2966 if (actualvariable >= 0)
2967 {
2968 int toremove = 0;
2969 if (actualvariable > minvariable && actualvariable < maxvariable)
2970 {
2971 std::vector<int>::const_iterator removeditvariable = removedvariables.begin();
2972 while (removeditvariable != removedvariables.end() && actualvariable > *removeditvariable)
2973 {
2974 ++toremove;
2975 ++removeditvariable;
2976 }
2977 }
2978 else if (actualvariable > maxvariable)
2979 {
2980 toremove = static_cast<int>(removedvariables.size());
2981 }
2982 edgeproperty.setvariableID(actualvariable - toremove);
2983 }
2984
2985 }
2986 }
2987 }
2988 catch (...)
2989 {
2990 _exhandler->raisefromcatch("", "FMTgraph::updatematrixindex", __LINE__, __FILE__);
2991 }
2992}
2993
2994}
2995
2996
2997
2998
2999namespace boost
3000 {
3001 namespace serialization
3002 {
3003 template<> struct guid_defined<Graph::FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>> : boost::mpl::true_
3004 {
3005
3006 };
3007 template<> struct guid_defined<Graph::FMTgraph<Graph::FMTbasevertexproperties, Graph::FMTbaseedgeproperties>> : boost::mpl::true_
3008 {
3009
3010 };
3011 template<> inline const char * guid<Graph::FMTgraph<Graph::FMTvertexproperties, Graph::FMTedgeproperties>>()
3012 {
3013 return "Graph::FMTgraph<Graph::FMTvertexproperties,Graph::FMTedgeproperties>";
3014 }
3015 template<> inline const char * guid<Graph::FMTgraph<Graph::FMTbasevertexproperties, Graph::FMTbaseedgeproperties>>()
3016 {
3017 return "Graph::FMTgraph<Graph::FMTbasevertexproperties,Graph::FMTbaseedgeproperties>";
3018 }
3019 }
3020 }
3021
3022
3023
3024
3025
3026
3027
3028
3029#endif // FMTGRAPH_H
3030
#define FMT_COMMA
Definition: FMTgraph.hpp:73
#define FMT_DBL_TOLERANCE
Definition: FMTutility.hpp:11
#define FMTEXPORT
Definition: FMTutility.hpp:92
The class keep information of a serie of actions in a given order.
Definition: FMTSerie.hpp:22
Definition: FMTaction.hpp:42
bool dorespectlock() const
Definition: FMTaction.hpp:160
std::string getname() const
Definition: FMTaction.hpp:151
Definition: FMTaction.hpp:327
std::unordered_set< int > getallaggregatesset(const std::vector< FMTaction > &actions, bool aggregateonly=false) const
Definition: FMTactualdevelopment.hpp:25
Definition: FMTconstraint.hpp:54
Definition: FMTdevelopment.hpp:44
std::vector< FMTdevelopmentpath > operate(const FMTaction &action, const FMTtransition &Transition, const Core::FMTyields &ylds, const std::vector< FMTtheme > &themes) const
int getlock() const
Definition: FMTdevelopment.hpp:90
FMTdevelopment clearlock() const
std::vector< bool > isanyworthtestingoperability(const std::vector< const FMTaction * > &actions, const std::vector< FMTaction > &allactions) const noexcept
const Core::FMTmask & getmask() const
Definition: FMTdevelopment.hpp:106
void setperiod(const int &lperiod)
bool operable(const FMTaction &action, const Core::FMTyields &ylds, const Graph::FMTgraphvertextoyield *graphyieldrequest=nullptr) const
bool anyoperable(const std::vector< const FMTaction * > &actions, const Core::FMTyields &ylds, const Graph::FMTgraphvertextoyield *graphyieldrequest=nullptr) const
int getage() const
Definition: FMTdevelopment.hpp:82
int getperiod() const
Definition: FMTdevelopment.hpp:98
FMTfuturdevelopment grow() const
Definition: FMTdevelopmentpath.hpp:19
Definition: FMTfuturdevelopment.hpp:24
Definition: FMTlookup.hpp:18
Definition: FMTmask.hpp:96
std::string get(const std::vector< FMTtheme > &themes) const
bool issubsetof(const boost::dynamic_bitset<> &rhs) const
Definition: FMTmask.hpp:352
FMTmask postsolve(const FMTmaskfilter &filter, const std::vector< FMTtheme > &basethemes) const
Definition: FMTmaskfilter.hpp:27
Definition: FMTobject.hpp:50
FMTobject & operator=(const FMTobject &rhs)
Definition: FMToutput.hpp:39
std::vector< FMToutputnode > getnodes(std::vector< std::string > &equation, double multiplier=1, bool orderbyoutputid=false, int period=1) const
bool canbenodesonly() const
std::vector< std::string > getdecomposition(const std::vector< FMTtheme > &themes) const
int targetthemeid() const
Definition: FMToutput.hpp:270
FMTtheme targettheme(const std::vector< FMTtheme > &themes) const
void fillfromshuntingyard(const std::vector< std::string >baseeq, std::map< std::string, double > &results, const std::vector< Core::FMToutputnode > &nodes, std::map< std::string, std::vector< std::string > > &allequations) const
Definition: FMToutputnode.hpp:20
double constant
Definition: FMToutputnode.hpp:24
int settograph(std::vector< int > &targetedperiods, int period, int max_period)
FMToutputsource factor
Definition: FMToutputnode.hpp:23
FMToutputsource source
Definition: FMToutputnode.hpp:22
Definition: FMToutputsource.hpp:40
bool isaction() const
Definition: FMToutputsource.hpp:190
const std::string & getaction() const
Definition: FMToutputsource.hpp:102
std::vector< const FMTaction * > targets(const std::vector< FMTaction > &actions) const
bool isvariablelevel() const
Definition: FMToutputsource.hpp:127
double getcoef(const FMTdevelopment &development, const FMTyields &yields, const Graph::FMTgraphvertextoyield *graphinfo=nullptr, std::vector< FMTdevelopmentpath > const *paths=nullptr, FMTaction const *action=nullptr) const
bool isnextperiod() const
Definition: FMToutputsource.hpp:154
bool isnull(const FMTyields &ylds) const
bool use(const FMTdevelopment &development, const FMTyields &ylds, const Graph::FMTgraphvertextoyield *graphinfo=nullptr) const
Definition: FMToutputsource.hpp:167
bool useinedges() const
Definition: FMToutputsource.hpp:150
int getthemetarget() const
Definition: FMToutputsource.hpp:84
Definition: FMTschedule.hpp:31
const std::map< FMTdevelopment, std::vector< double > > & at(const FMTaction &action) const
iterator find(const FMTaction &actionkey)
void addevent(const Core::FMTdevelopment &dev, const double &area, const Core::FMTaction &action)
Definition: FMTbounds.hpp:342
bool emptylock() const
Definition: FMTtheme.hpp:47
const std::vector< std::string > & getbaseattributes() const
Definition: FMTtheme.hpp:289
Definition: FMTbaseedgeproperties.hpp:26
virtual double getproportion() const
Definition: FMTbaseedgeproperties.hpp:48
void setactionID(const int &newid)
virtual int getvariableID() const
Definition: FMTbaseedgeproperties.hpp:44
int getactionID() const
Definition: FMTbaseedgeproperties.hpp:52
Definition: FMTbasevertexproperties.hpp:23
void setdevlopementmask(const Core::FMTmask &newmask)
const Core::FMTdevelopment & get() const
Definition: FMTbasevertexproperties.hpp:65
Definition: FMTedgeproperties.hpp:20
int getvariableID() const override
Definition: FMTedgeproperties.hpp:36
void setvariableID(const int &newvariableID)
double getproportion() const override
Definition: FMTedgeproperties.hpp:41
Definition: FMTgraph.hpp:78
void cleardevelopments()
Definition: FMTgraph.hpp:317
virtual ~FMTgraph()=default
FMTinedge_iterator getlastdisturbance(FMTinedge_iterator activeedge, int &periodtolastdisturbance) const
Definition: FMTgraph.hpp:1993
FMTvertex_descriptor adddevelopment(const Core::FMTfuturdevelopment &futurdevelopement, boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > &alldevs, bool forcenewone=false)
Definition: FMTgraph.hpp:837
const Core::FMTdevelopment & getdevelopment(const FMTvertex_descriptor &descriptor) const
Definition: FMTgraph.hpp:833
Core::FMTschedule getoutvariablesproportions(const std::vector< Core::FMTaction > &actions, const double *actual_solution, const int &lperiod, bool withlock=false) const
Definition: FMTgraph.hpp:2540
std::map< std::string, std::map< int, double > > locatenodebytheme(const Models::FMTmodel &model, Core::FMToutputnode output_node, int period) const
Definition: FMTgraph.hpp:1221
std::vector< int > getinvariables(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1394
std::vector< FMTvertex_pair >::const_iterator getfirstconstblock() const
Definition: FMTgraph.hpp:165
boost::graph_traits< FMTadjacency_list >::vertex_iterator FMTvertex_iterator
Definition: FMTgraph.hpp:114
bool sameedgesas(const FMTgraph &rhs) const
Definition: FMTgraph.hpp:1958
std::queue< FMTvertex_descriptor > initialize(const std::vector< Core::FMTactualdevelopment > &actdevelopments)
Definition: FMTgraph.hpp:351
bool onlypertiodstart(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1072
void addaction(const int &actionID, FMTgraphstats &statsdiff, std::queue< FMTvertex_descriptor > &actives, const FMTvertex_descriptor &out_vertex, const std::vector< Core::FMTdevelopmentpath > &paths)
Definition: FMTgraph.hpp:942
FMTgraphstats stats
Definition: FMTgraph.hpp:123
std::queue< FMTvertex_descriptor > getactiveverticies() const
Definition: FMTgraph.hpp:1626
std::map< std::string, double > getvalues(const Models::FMTmodel &model, const std::vector< FMTvertex_descriptor > &verticies, const Core::FMToutputnode &node, const Core::FMTtheme &theme, const double *solution, Core::FMToutputlevel level) const
Definition: FMTgraph.hpp:1798
const FMTvertex_descriptor * getvertexfromvertexinfo(const Graph::FMTgraphvertextoyield *info) const
Definition: FMTgraph.hpp:1783
std::vector< FMToutputnodecache< FMTvertex_descriptor FMT_COMMA FMTvertex_iterator > > nodescache
Definition: FMTgraph.hpp:121
void updatematrixindex(const std::vector< int > &removedvariables, const std::vector< int > &removedconstraints)
Definition: FMTgraph.hpp:1983
std::vector< FMTvertex_descriptor > getactionsources(const FMTvertex_descriptor &out_vertex, const int &actionid) const
Definition: FMTgraph.hpp:1012
void setstats(const FMTgraphstats &newstats)
Definition: FMTgraph.hpp:1551
void rebasecache()
Definition: FMTgraph.hpp:1902
std::map< int, int > getoutvariables(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1452
boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > getdevsset(const int &period) const
Definition: FMTgraph.hpp:329
FMTgraphstats buildschedule(const Models::FMTmodel &model, std::queue< FMTvertex_descriptor > actives, const Core::FMTschedule &schedule)
Definition: FMTgraph.hpp:1556
std::vector< Core::FMTdevelopmentpath > getpaths(const FMTvertex_descriptor &out_vertex, const int &actionID) const
Definition: FMTgraph.hpp:1140
FMTgraph(const FMTgraph &rhs)
Definition: FMTgraph.hpp:242
int getfirstactiveperiod() const
Definition: FMTgraph.hpp:1988
std::pair< FMToutedge_iterator, FMToutedge_iterator > FMToutedge_pair
Definition: FMTgraph.hpp:116
std::set< Core::FMTSerie > getallseries(FMTvertex_descriptor targetdescriptor, const std::string &seriestarter, const std::vector< Core::FMTaction > &actions, const std::unordered_set< int > &actionselected, const Core::FMTmask &mask) const
Definition: FMTgraph.hpp:2223
std::vector< FMTpredictor > getpredictors(const FMTvertex_descriptor &targetdescriptor, const Models::FMTmodel &model, const std::vector< std::string > &yieldnames, const size_t &depth, bool periodonevalues=false, bool withGCBMid=true) const
Definition: FMTgraph.hpp:2337
boost::adjacency_list< boost::listS, boost::listS, boost::bidirectionalS, tvertexproperties, tedgeproperties, boost::no_property, boost::listS > FMTadjacency_list
Definition: FMTgraph.hpp:107
bool periodstop(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1116
bool gettransferrow(const FMTvertex_descriptor &vertex_descriptor, std::vector< int > &row_starts, std::vector< int > &cols, std::vector< double > &cols_value) const
Definition: FMTgraph.hpp:1666
std::map< std::string, double > getsource(const Models::FMTmodel &model, const Core::FMToutputnode &node, int period, const Core::FMTtheme &theme, const double *solution, Core::FMToutputlevel level=Core::FMToutputlevel::standard) const
Definition: FMTgraph.hpp:1755
size_t nedges() const
Definition: FMTgraph.hpp:1692
std::vector< std::string > getactionserie(FMTvertex_descriptor targetdescriptor, const size_t &maxactions, const std::vector< Core::FMTaction > &actions) const
Definition: FMTgraph.hpp:2179
FMTgraphbuild getbuildtype() const
Definition: FMTgraph.hpp:321
std::vector< FMTvertex_descriptor > getnode(const Models::FMTmodel &model, Core::FMToutputnode &output_node, int period) const
Definition: FMTgraph.hpp:1258
void generatedevelopments()
Definition: FMTgraph.hpp:1917
FMTgraphstats eraseperiod(std::vector< int > &deletedconstraints, std::vector< int > &deletedvariables, bool keepbounded=false)
Definition: FMTgraph.hpp:1614
bool isvalidouputnode(const Models::FMTmodel &model, const Core::FMToutputnode &node, std::vector< const Core::FMTaction * > &action_IDS, int period) const
Definition: FMTgraph.hpp:1161
void filluplastactions(const int &targetperiod, const FMTvertex_descriptor &targetdescriptor, std::vector< const FMTbaseedgeproperties * > &lastactions, std::vector< int > &distances, const size_t &depth) const
Definition: FMTgraph.hpp:2024
void getinitialbounds(std::vector< double > &lower_bounds, std::vector< double > &upper_bounds) const
Definition: FMTgraph.hpp:1673
Core::FMTschedule getschedule(const std::vector< Core::FMTaction > &actions, const double *actual_solution, const int &lperiod, bool withlock=false) const
Definition: FMTgraph.hpp:2419
size_t getamountofpaths(const Core::FMTdevelopment &dev, const int &actionid, const Models::FMTmodel &model, const boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > &actualperioddevs) const
Definition: FMTgraph.hpp:2062
void setbuildtype(const FMTgraphbuild &build)
Definition: FMTgraph.hpp:325
boost::graph_traits< FMTadjacency_list >::in_edge_iterator FMTinedge_iterator
Definition: FMTgraph.hpp:112
bool periodstart(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1052
bool containsdevelopment(const Core::FMTdevelopment &development, const boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > &alldevs) const
Definition: FMTgraph.hpp:345
bool isdependant(const FMTvertex_descriptor &descriptor, const int &theactionid, bool &newedge) const
Definition: FMTgraph.hpp:188
std::map< int, double > getvariables(const Models::FMTmodel &model, const Core::FMToutputnode &output_node, const std::vector< FMTvertex_descriptor > &verticies) const
Definition: FMTgraph.hpp:1342
double getinproportion(const FMTvertex_descriptor &vertex_descriptor) const
Definition: FMTgraph.hpp:516
FMTvertex_descriptor adddevelopment(const Core::FMTfuturdevelopment &futurdevelopement)
Definition: FMTgraph.hpp:858
std::map< std::string, double > getoutput(const Models::FMTmodel &model, const Core::FMToutput &output, int period, const double *solution, Core::FMToutputlevel level=Core::FMToutputlevel::standard) const
Definition: FMTgraph.hpp:740
void getvariablenames(const std::vector< Core::FMTaction > &actions, std::vector< std::string > &colnames) const
Definition: FMTgraph.hpp:616
void addaction(const int &actionID, FMTgraphstats &statsdiff, std::queue< FMTvertex_descriptor > &actives, const FMTvertex_descriptor &out_vertex, const std::vector< Core::FMTdevelopmentpath > &paths, boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > &devsets, bool inserie=false)
Definition: FMTgraph.hpp:892
void gettransferrownames(std::vector< std::string > &rownames) const
Definition: FMTgraph.hpp:692
std::vector< FMTvertex_descriptor > getnodebystaticmask(const Models::FMTmodel &model, const Core::FMToutputnode &node, int period) const
Definition: FMTgraph.hpp:1697
void postsolve(const Core::FMTmaskfilter &filter, const std::vector< Core::FMTtheme > &originalbasethemes, const std::vector< int > &actionmapconnection)
Definition: FMTgraph.hpp:2379
void clearcache()
Definition: FMTgraph.hpp:313
FMTgraphstats * getstatsptr()
Definition: FMTgraph.hpp:1547
int getfirstperiod() const
Definition: FMTgraph.hpp:2375
int getperiod() const
Definition: FMTgraph.hpp:1888
size_t timesincelastaction(const FMTvertex_descriptor &targetdescriptor) const
Definition: FMTgraph.hpp:2306
FMTgraphstats build(const Models::FMTmodel &model, std::queue< FMTvertex_descriptor > actives, int compressageoperability=1)
Definition: FMTgraph.hpp:419
size_t size() const
Definition: FMTgraph.hpp:1658
std::vector< Core::FMTactualdevelopment > getperiodstopdev(const int location, const double *actual_solution) const
Definition: FMTgraph.hpp:718
std::map< int, int > getinidsvariables(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1432
std::vector< int > getoutactions(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1473
FMTgraph()
Definition: FMTgraph.hpp:219
std::vector< FMTvertex_pair >::iterator getfirstblock()
Definition: FMTgraph.hpp:141
const FMTvertex_pair & getperiodverticies(int period) const
Definition: FMTgraph.hpp:1644
FMTgraphstats getstats() const
Definition: FMTgraph.hpp:1543
FMTvertex_descriptor getdevelopment(const Core::FMTdevelopment &developement, const boost::unordered_set< Core::FMTlookup< FMTvertex_descriptor, Core::FMTdevelopment > > &alldevs) const
Definition: FMTgraph.hpp:827
bool constraintlenght(const Core::FMTconstraint &constraint, int &start, int &stop) const
Definition: FMTgraph.hpp:1520
boost::graph_traits< FMTadjacency_list >::vertex_descriptor FMTvertex_descriptor
Definition: FMTgraph.hpp:110
std::vector< double > getinproportions(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:1413
FMTgraph(const FMTgraphbuild lbuildtype)
Definition: FMTgraph.hpp:231
bool anyoperables(const FMTvertex_descriptor &descriptor, const std::vector< int > &action_ids) const
Definition: FMTgraph.hpp:1373
std::vector< Core::FMTaction >::const_iterator getactionoffirstserie(const FMTvertex_descriptor &targetdescriptor, std::vector< Core::FMTaction >::const_iterator theaction, const size_t &seriemaxsize, const std::vector< Core::FMTaction > &actions) const
Definition: FMTgraph.hpp:2127
FMTvertex_descriptor getgrowthsource(const FMTvertex_descriptor &out_vertex) const
Definition: FMTgraph.hpp:993
void setconstraintID(const FMTvertex_descriptor &vertex, const int &id)
Definition: FMTgraph.hpp:1662
boost::graph_traits< FMTadjacency_list >::edge_descriptor FMTedge_descriptor
Definition: FMTgraph.hpp:111
std::set< Core::FMTSerie > getrorations(const Models::FMTmodel &model, const Core::FMTmask &mask, const std::string &aggregate) const
Definition: FMTgraph.hpp:2492
std::vector< FMToutputnodecache< FMTvertex_descriptorFMT_COMMAFMTvertex_iterator > >::reverse_iterator reversecachenodeit
Definition: FMTgraph.hpp:122
bool keepforserie(const FMTvertex_descriptor &targetdescriptor, std::vector< Core::FMTaction >::const_iterator theaction, const size_t &seriemaxsize, const std::vector< Core::FMTaction > &actions, bool &onserie) const
Definition: FMTgraph.hpp:2149
boost::graph_traits< FMTadjacency_list >::edge_iterator FMTedge_iterator
Definition: FMTgraph.hpp:115
void swap(FMTgraph &rhs)
Definition: FMTgraph.hpp:253
FMTadjacency_list data
Definition: FMTgraph.hpp:108
std::vector< FMTvertex_pair > developments
Definition: FMTgraph.hpp:120
size_t hash(size_t seed=0) const
Definition: FMTgraph.hpp:874
bool empty() const
Definition: FMTgraph.hpp:1621
bool isnotransfer(const FMTvertex_descriptor &descriptor, size_t outcount=0) const
Definition: FMTgraph.hpp:491
double outarea(const FMTvertex_descriptor &out_vertex, const int &actionID, const double *&solution) const
Definition: FMTgraph.hpp:968
std::pair< FMTvertex_iterator, FMTvertex_iterator > FMTvertex_pair
Definition: FMTgraph.hpp:117
bool isanyoperables(const FMTvertex_descriptor &descriptor, const std::vector< bool > &actionsop) const noexcept
Definition: FMTgraph.hpp:1346
std::vector< const Core::FMTaction * > selectedactions(const Models::FMTmodel &model, const std::vector< int > &action_IDS) const
Definition: FMTgraph.hpp:1500
std::vector< const Core::FMTdevelopment * > nochoice(const Core::FMTmask &basemask, const int &death_id) const
Definition: FMTgraph.hpp:563
double inarea(const FMTvertex_descriptor &out_vertex, const double *&solution, int actionid=-1, bool growth=false) const
Definition: FMTgraph.hpp:1032
boost::graph_traits< FMTadjacency_list >::out_edge_iterator FMToutedge_iterator
Definition: FMTgraph.hpp:113
bool isvalidgraphnode(const Models::FMTmodel &model, const FMTvertex_descriptor &vertex_descriptor, const Core::FMToutputnode &node, const std::vector< const Core::FMTaction * > &selected) const
Definition: FMTgraph.hpp:1181
int getmaximalock(const int &period)
Definition: FMTgraph.hpp:1096
FMTgraphbuild buildtype
Definition: FMTgraph.hpp:119
Graph::FMTgraphvertextoyield getvertextoyieldinfo(const Models::FMTmodel &model, const FMTvertex_descriptor &descriptor) const
Definition: FMTgraph.hpp:1772
FMTgraphstats naturalgrowth(std::queue< FMTvertex_descriptor > actives, FMTgraphstats statsdiff, bool typeIImatrix=false, bool splitgrowth=false)
Definition: FMTgraph.hpp:521
std::map< int, double > locatenode(const Models::FMTmodel &model, Core::FMToutputnode output_node, int period) const
Definition: FMTgraph.hpp:1206
Definition: FMTgraphstats.hpp:28
int cols
Number of columns in the matrix of FMTlpsolver.
Definition: FMTgraphstats.hpp:48
Definition: FMTgraphvertextoyield.hpp:27
const void * getvertexptr() const
Definition: FMTgraphvertextoyield.hpp:47
Definition: FMToutputnodecache.hpp:27
Definition: FMTvertexproperties.hpp:28
void setconstraintID(const int &ID)
int getconstraintID() const override
Definition: FMTvertexproperties.hpp:49
Definition: FMTmodel.hpp:60
Core::FMTyields yields
Yields data comming from the yield file.
Definition: FMTmodel.hpp:595
bool isstaticnode(const Core::FMToutputnode &node, double ratioofset=0.1) const
Core::FMTmask getstaticmask(const Core::FMToutputnode &node, bool ignoreoutputvariables=false) const
std::vector< Core::FMTtheme > themes
Model themes of the landscape section file.
Definition: FMTmodel.hpp:586
std::vector< Core::FMTtransition > transitions
Model transitions from the transition file and also the _death transition.
Definition: FMTmodel.hpp:592
size_t getseriesmaxsize() const
int getparameter(const FMTintmodelparameters &key) const
bool useactionserie() const
std::vector< Core::FMTaction > actions
Model actions from the action file and also the _death action.
Definition: FMTmodel.hpp:589
The Core namespace provides classes for simulating stands/strata growth/harvest through time.
Definition: FMTaction.hpp:31
FMToutputlevel
Definition: FMTutility.hpp:17
@ developpement
Definition: FMTutility.hpp:20
@ totalonly
Definition: FMTutility.hpp:19
@ standard
Definition: FMTutility.hpp:18
@ actual
Definition: FMTutility.hpp:76
@ val
Definition: FMTutility.hpp:77
@ FMTunsupported_output
Definition: FMTexception.hpp:77
@ FMTfunctionfailed
Definition: FMTexception.hpp:95
@ FMTinvalid_action
Definition: FMTexception.hpp:51
@ FMTsourcetotarget_transition
Definition: FMTexception.hpp:121
@ FMTrangeerror
Definition: FMTexception.hpp:100
Namespace for using/building unidirectional graphs in FMT.
Definition: FMTareaparser.hpp:31
FMTgraphbuild
Definition: FMTgraph.hpp:67
@ MATRIX_TYPE
Definition: FMTmodelparameters.hpp:30
Definition: FMTaction.hpp:364