27 #include "antares/solver/constraints-builder/cbuilder.h"
28 #include "antares/solver/constraints-builder/grid.h"
32 namespace Antares::Graph
43 for (
auto i = pEdgesList.begin(); i != pEdgesList.end(); i++)
47 for (
auto i = pNodesList.begin(); i != pNodesList.end(); i++)
56 auto nodeIT = std::find_if(pNodesList.begin(),
58 [&
id](
const NodeP& nodeP) ->
bool
59 { return nodeP->getName() == id; });
61 if (nodeIT == pNodesList.end())
65 pNodesList.push_back(newNode);
77 std::string s1(n1->getName());
78 std::string s2(n2->getName());
79 EdgeP edgePtr = findEdgeFromNodeNames(s1, s2);
80 if (edgePtr ==
nullptr)
84 newEdge->setWeight(weight);
87 pEdgesList.push_back(newEdge);
93 adjency[newEdge->getOrigin()].insert(std::make_pair(newEdge->getDestination(), newEdge));
94 adjency[newEdge->getDestination()].insert(std::make_pair(newEdge->getOrigin(), newEdge));
104 template<
class NodeT>
110 for (
auto i = pNodesList.begin(); i != pNodesList.end(); i++)
112 uf.insert(std::make_pair(*i, *i));
116 for (
auto i = pEdgesList.begin(); i != pEdgesList.end(); i++)
119 if (uf[(*i)->getOrigin()] != uf[(*i)->getDestination()])
122 NodeP cset(uf[(*i)->getDestination()]);
123 for (
auto j = pNodesList.begin(); j != pNodesList.end(); j++)
127 uf[*j] = uf[(*i)->getOrigin()];
133 std::unordered_map<NodeP, bool> cVec;
134 for (
auto cIT = uf.begin(); cIT != uf.end(); cIT++)
136 cVec[cIT->second] =
true;
139 return (uint)(cVec.size());
142 template<
class NodeT>
146 pMinSpanningTree.clear();
151 for (
auto i = pNodesList.begin(); i != pNodesList.end(); i++)
153 uf.insert(std::make_pair(*i, *i));
157 VectorEdgeP tempEdgesList = pEdgesList;
158 std::stable_sort(tempEdgesList.begin(),
163 for (
auto i = tempEdgesList.begin(); i != tempEdgesList.end(); i++)
166 if (uf[(*i)->getOrigin()] != uf[(*i)->getDestination()])
168 pMinSpanningTree.push_back(*i);
171 NodeP cset(uf[(*i)->getDestination()]);
172 for (
auto j = pNodesList.begin(); j != pNodesList.end(); j++)
176 uf[*j] = uf[(*i)->getOrigin()];
183 template<
class NodeT>
189 if (pMinSpanningTree.empty())
196 meshIndexMatrix.clear();
199 std::vector<EdgeP> linksToBeAdded;
200 for (
auto i = pEdgesList.begin(); i != pEdgesList.end(); i++)
203 if (std::find(pMinSpanningTree.begin(), pMinSpanningTree.end(), (*i))
204 == pMinSpanningTree.end())
206 linksToBeAdded.push_back(*i);
210 std::vector<EdgeIncidence> incidenceMatrix(linksToBeAdded.size());
211 for (uint i = 0; i < linksToBeAdded.size(); i++)
213 incidenceMatrix[i] = getIncidenceVector(linksToBeAdded[i]);
216 for (uint i = 0; i < linksToBeAdded.size(); i++)
218 logs.info() <<
"Searching basis (loop " << i + 1 <<
"/" << linksToBeAdded.size() <<
")";
221 getDuplicatedGrid(polarisedDuplicate);
222 VectorEdgeP v = getEdgeVectorFromIncidence(incidenceMatrix[i]);
225 VectorNodeP adjacentNodes;
228 for (uint j = 0; j < v.size(); j++)
230 if (std::find(adjacentNodes.begin(), adjacentNodes.end(), v[j]->getOrigin())
231 == adjacentNodes.end())
233 adjacentNodes.push_back(v[j]->getOrigin());
235 if (std::find(adjacentNodes.begin(), adjacentNodes.end(), v[j]->getDestination())
236 == adjacentNodes.end())
238 adjacentNodes.push_back(v[j]->getDestination());
242 v[j]->getDestination()->getName()
249 polarisedDuplicate.
addEdge(ni1, ni2, ei->getWeight());
250 polarisedDuplicate.removeEdge(ei);
253 v[j]->getDestination()->getName() +
"-");
255 ni1 = polarisedDuplicate.
findNodeFromName(v[j]->getOrigin()->getName() +
"-");
256 ni2 = polarisedDuplicate.
findNodeFromName(v[j]->getDestination()->getName() +
"+");
258 polarisedDuplicate.
addEdge(ni1, ni2, ei->getWeight());
259 polarisedDuplicate.removeEdge(ei);
263 v = polarisedDuplicate.twoLevelPath(adjacentNodes);
267 std::vector<int> edgeIndices;
268 for (
typename VectorEdgeP::iterator e = v.begin(); e != v.end(); e++)
270 auto name1 = (*e)->getOrigin()->getName();
271 name1 = name1.substr(0, name1.length() - 1);
272 auto name2 = (*e)->getDestination()->getName();
273 name2 = name2.substr(0, name2.length() - 1);
274 EdgeP ei = findEdgeFromNodeNames(name1, name2);
277 auto eIT = std::find(pEdgesList.begin(), pEdgesList.end(), ei);
278 int pos = (int)std::distance(pEdgesList.begin(), eIT);
279 edgeIndices.push_back(pos);
283 EdgeIncidence I = getIncidenceVector(Ci);
284 meshIndexMatrix.push_back(edgeIndices);
286 for (uint j = i + 1; j < linksToBeAdded.size(); j++)
288 if (incidenceInnerProduct(I, incidenceMatrix[j]) == 1)
290 incidenceMatrix[j] = incidenceXOR(incidenceMatrix[i], incidenceMatrix[j]);
302 template<
class NodeT>
306 for (
typename VectorNodeP::iterator node = pNodesList.begin(); node != pNodesList.end(); node++)
309 grid.
addNode((*(*node)->nodeProperties), (*node)->getName() +
"+");
313 grid.
addNode((*(*node)->nodeProperties), (*node)->getName() +
"-");
318 for (
typename VectorEdgeP::iterator e = pEdgesList.begin(); e != pEdgesList.end(); e++)
321 auto nodeOrigIT = std::find_if(grid.pNodesList.begin(),
322 grid.pNodesList.end(),
323 [&e](
const NodeP& nodeP) ->
bool {
324 return nodeP->getName()
325 == (*e)->getOrigin()->getName() +
"+";
328 auto nodeDestIT = std::find_if(grid.pNodesList.begin(),
329 grid.pNodesList.end(),
330 [&e](
const NodeP& nodeP) ->
bool {
331 return nodeP->getName()
332 == (*e)->getDestination()->getName() +
"+";
335 grid.
addEdge(*nodeOrigIT, *nodeDestIT, (*e)->getWeight());
339 auto nodeOrigIT = std::find_if(grid.pNodesList.begin(),
340 grid.pNodesList.end(),
341 [&e](
const NodeP& nodeP) ->
bool {
342 return nodeP->getName()
343 == (*e)->getOrigin()->getName() +
"-";
346 auto nodeDestIT = std::find_if(grid.pNodesList.begin(),
347 grid.pNodesList.end(),
348 [&e](
const NodeP& nodeP) ->
bool {
349 return nodeP->getName()
350 == (*e)->getDestination()->getName() +
"-";
353 grid.
addEdge(*nodeOrigIT, *nodeDestIT, (*e)->getWeight());
363 template<
class NodeT>
367 for (
typename VectorNodeP::iterator node = pNodesList.begin(); node != pNodesList.end(); node++)
370 grid.
addNode((*(*node)->nodeProperties), (*node)->getName());
375 for (
typename VectorEdgeP::iterator e = pEdgesList.begin(); e != pEdgesList.end(); e++)
378 auto nodeOrigIT = std::find_if(grid.pNodesList.begin(),
379 grid.pNodesList.end(),
380 [&e](
const NodeP& nodeP) ->
bool {
381 return nodeP->getName()
382 == (*e)->getOrigin()->getName();
385 auto nodeDestIT = std::find_if(grid.pNodesList.begin(),
386 grid.pNodesList.end(),
387 [&e](
const NodeP& nodeP) ->
bool {
388 return nodeP->getName()
389 == (*e)->getDestination()->getName();
392 grid.
addEdge(*nodeOrigIT, *nodeDestIT, (*e)->getWeight());
398 template<
class NodeT>
401 VectorEdgeP SP, minSP;
402 double minLength = DBL_MAX, length;
403 for (
typename VectorNodeP::iterator n = vN.begin(); n != vN.end(); n++)
405 SP = findShortestPath(findNodeFromName((*n)->getName() +
"+"),
406 findNodeFromName((*n)->getName() +
"-"));
407 length = std::accumulate(SP.begin(),
411 if (length < minLength)
422 template<
class NodeT>
425 assert(node1 != node2);
429 std::map<NodeP, double> dist;
430 std::map<NodeP, NodeP> prev;
433 [[maybe_unused]]
bool checkNode1(
false), checkNode2(
false);
434 VectorNodeP nodes = pNodesList;
436 for (
auto i = nodes.begin(); i != nodes.end(); i++)
444 else if ((*i) == node2)
449 assert(checkNode1 && checkNode2);
456 std::pair<Grid::NodeP, double> u(
nullptr, inf - 1);
457 typename Grid::VectorNodeP::iterator ui;
458 for (
auto i = nodes.begin(); i != nodes.end(); i++)
460 if (dist[(*i)] < u.second)
463 u.second = dist[(*i)];
469 if (u.first == node2)
479 for (
auto i = adjency.at(u.first).begin(); i != adjency.at(u.first).end(); i++)
481 if (i->second ==
nullptr)
486 if ((u.second + i->second->getWeight()) < dist[i->first])
488 dist[i->first] = u.second + i->second->getWeight();
489 prev[i->first] = u.first;
495 Grid::VectorEdgeP path;
498 while (prev[currentNode] !=
nullptr)
500 path.push_back(adjency.at(currentNode).at(prev[currentNode]));
501 currentNode = prev[currentNode];
Antares Grid (graph)
Definition: grid.h:127
EdgeP addEdge(NodeP, NodeP, long weight=0)
Add one edge to the graph.
Definition: grid.hxx:75
VectorEdgeP findShortestPath(NodeP node1, NodeP node2) const
Find shortest path between the two nodes (Djikstra)
Definition: grid.hxx:423
NodeP addNode(NodeT &, std::string)
Add one node to the graph.
Definition: grid.hxx:54
bool cloneGrid(Grid &)
get a clone of the Grid
Definition: grid.hxx:364
~Grid()
Destructor.
Definition: grid.hxx:41
NodeP findNodeFromName(std::string name)
find a node from it's name
Definition: grid.h:231
void kruskal()
Kruskal algorithm.
Definition: grid.hxx:143
bool getDuplicatedGrid(Grid &)
get a Gid where edges and nodes are duplicated
Definition: grid.hxx:303
EdgeP findEdgeFromNodeNames(std::string u, std::string v)
find an edge from node names
Definition: grid.h:156
bool buildMesh()
Get minimum spanning tree.
Definition: grid.hxx:184