-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNewClasses.cpp
158 lines (125 loc) · 4.29 KB
/
NewClasses.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
// Created by nandgate on 9/5/24.
//
#include "NewClasses.h"
void Diagram::build(const vector<pair<int,int>> processingOrder, Node &node, int index) {
// set the node to the root and start from there.
vector<int> currentLayer; // should be base layer.
currentLayer.push_back(node.id);
//int lastInserted = 0;
//tree.push_back({0});
Node root(node);
root.children.clear();
root.parents.clear();
// insert root to nodes.
tree.push_back(currentLayer);
auto start = processingOrder.begin()+index;
auto end = processingOrder.end();
for (; start < end; start++){
auto[a,b] = *start;
vector<int>&& nextLayer = buildNextLayer(currentLayer, index);
tree.push_back(nextLayer);
currentLayer = std::move(nextLayer);
}
}
vector<int>&& Diagram::buildNextLayer(vector<int>& currentLayer, int index) {
/*
* build next layer from the given current layer.
* should also create arcs and store them in the map.
* should also create nodes and store them in the map.
*/
vector<int> nextLayer;
//set<pair<set<int>,int>> allStates;
for (auto id: currentLayer){ // iterate through current layer.
auto& node = nodes[id];
// add zero state
Node zeroNode;
zeroNode.id = lastNode++; // TODO: need to add some more fields.
zeroNode.states = node.states;
Arc zeroArc(lastArc++, zeroNode.id, id, 0);
node.children.push_back(zeroArc.id);
zeroNode.parents.push_back(zeroArc.id);
// insert to map.
nodes.insert({zeroNode.id, zeroNode});
arcs.insert({zeroArc.id, zeroArc});
nextLayer.push_back(zeroNode.id);
for (auto state: node.states){
// create arc and node
Node node1;// create a new node with some Id
node1.id = lastNode++;
auto states = node.states; // remove the state from states.
states.erase(std::remove(states.begin(), states.end(), state), states.end());
node1.states = std::move(states);
Arc arc( lastArc++, node1.id, id, state);
node1.parents.push_back(arc.id);
node.children.push_back(arc.id); // NOTE: SHOULD BE ID OF THE CHILDARC, NOT CHILD NODE.
//Arc arc(lastArc++, 10, 10, 10);
nodes.insert({node1.id, node1});
arcs.insert({arc.id, arc});
nextLayer.push_back(node1.id); // ASAP: remove the state from the list of states and
}
}
return std::move(nextLayer);
}
void Diagram::mergeNodes(Node& node1, Node& node2) {
/*
* Merge node2 with node1. Updates node1 attributes and removes node2 from dictionary.
* Used in reduceNodes().
*/
for (auto parent: node2.parents){
auto& arc = arcs[parent];
arc.head = node1.id; // TODO: change other attributes if needed
}
for (auto child: node2.children){
auto& arc = arcs[child];
arc.tail = node1.id; // TODO: change other attributes if needed.
}
// update node1 parents to add node2's parents.
node1.parents.insert(node1.parents.end(), node2.parents.begin(), node2.parents.end());
node1.children.insert(node1.children.end(), node2.children.begin(), node2.children.end());
node2.parents.clear();
node2.children.clear();
}
void Diagram::reduceLayer(vector<uint>& currentLayer) {
/*
* Merge two nodes that containing same state. Update incoming and outgoing arcs to point to merged node.
*/
vector<bool> filter(currentLayer.size());
unordered_set<tuple<unordered_set<int>,int,int>,tuple_hash,tuple_equal> allStates;
uint j = 0;
for (auto i: currentLayer){
auto& node = nodes[i];
auto [it,isInserted] = allStates.insert({node.states, node.state2, i});
if (!isInserted) { // already exists, merge both nodes.
auto& [temp_state, temp_stat2, pos ] = *(it);
// get node from dict with pos as key and update its attributes.
auto& node2 = nodes[pos];
mergeNodes(node2, node);
// delete node from nodes.
nodes.erase(node.id);
filter[j] = true;
}
j++;
}
// remove filtered nodeIds from current layer.
currentLayer.erase(std::remove_if(currentLayer.begin(), currentLayer.end(),
[&filter](int x){return filter[x];}),
currentLayer.end());
}
static void printTree(const vector<vector<int>>& tree){
for (const auto& layer: tree){
for (const int node: layer){
cout << node << " ";
}
cout << endl;
}
}
int main(){
// some processing order
vector<pair<int,int>> processingOrder = {{1,2},{2,3}};
Diagram diagram;
Node rootNode;
rootNode.states = unordered_set<int>({2,3,4});
diagram.build(processingOrder, rootNode, 0);
printTree(diagram.tree);
}