COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/new_map_win.cc @ 1887:22fdc00894aa

Last change on this file since 1887:22fdc00894aa was 1887:22fdc00894aa, checked in by Hegyi Péter, 14 years ago

The tree that is created for evaluation of expression string at new map creation is deleted after usage.

File size: 10.1 KB
Line 
1#include <new_map_win.h>
2
3bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e)
4{
5  if(e->keyval==GDK_Escape)
6  {
7    hide();
8  }
9  return true;
10}
11
12NewMapWin::NewMapWin(const std::string& title, NoteBookTab & mw, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),mytab(mw),node("Create NodeMap"),edge("Create EdgeMap")
13{
14  set_default_size(200, 50);
15
16  signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed));
17
18  Gtk::VBox * vbox=get_vbox();
19
20  //entries
21  table=new Gtk::Table(3, 2, false);
22
23  label=new Gtk::Label;
24  label->set_text("Name of new map:");
25  name.set_text("");
26
27  (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
28  (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
29
30  label=new Gtk::Label;
31  label->set_text("Default value in the map:");
32  default_value.set_text("0");
33
34  (*table).attach(*label,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
35  (*table).attach(default_value,1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
36
37  //node vs. edge map selector
38  Gtk::RadioButton::Group group = node.get_group();
39  edge.set_group(group);
40 
41  if(edgenode)
42    {
43      (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
44      (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
45    }
46  else
47    {
48      if(itisedge)
49        {
50          edge.set_active();
51        }
52      else
53        {
54          node.set_active();
55        }
56    }
57
58  vbox->pack_start(*table);
59
60  //OK button
61  add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
62
63  show_all_children();
64
65}
66
67void NewMapWin::on_response(int response_id)
68{
69  if(response_id==Gtk::RESPONSE_OK)
70    {
71      double def_val=0;
72
73      //get and formulate text
74      std::string def_val_str=default_value.get_text();
75      std::string polishform=string2Polishform(def_val_str,edge.get_active());
76
77      //get name of text
78      std::string mapname=name.get_text();
79
80      if(!mapname.empty()&&!polishform.empty())
81        {
82          int abortion=0;
83          if(edge.get_active())
84            {
85              //create the new map
86              Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mytab.mapstorage.graph);
87
88              std::stack<double> polishstack;
89 
90              for(EdgeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
91                {
92                  for(int i=0;i<(int)polishform.size();i++)
93                    {
94                      double op1, op2;
95                      bool operation=true;
96                      switch(polishform[i])
97                        {
98                        case '+':
99                        case '-':
100                        case '/':
101                        case '*':
102                          op1=polishstack.top();
103                          polishstack.pop();
104                          op2=polishstack.top();
105                          polishstack.pop();
106                          break;
107                        default:
108                          //substitute variable
109                          std::map< std::string,Graph::EdgeMap<double> * > ems=mytab.mapstorage.edgemap_storage;
110                          bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
111                          if(itisvar)
112                            {
113                              polishstack.push( (*(mytab.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
114                            }
115                          else
116                            {
117                              polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
118                            }
119                          operation=false;
120                          break;
121                        }
122                      if(operation)
123                        {
124                          double res;
125                          switch(polishform[i])
126                            {
127                            case '+':
128                              res=op1+op2;
129                              break;
130                            case '-':
131                              res=op2-op1;
132                              break;
133                            case '/':
134                              res=op2/op1;
135                              break;
136                            case '*':
137                              res=op1*op2;
138                              break;
139                            default:
140                              std::cout << "How could we get here?" << std::endl;
141                              break;
142                            }
143                          polishstack.push(res);
144                        }
145                    }
146                  (*emptr)[k]=polishstack.top();
147                }
148
149              //if addition was not successful addEdgeMap returns one.
150              //cause can be that there is already a map named like the new one
151              if(mytab.mapstorage.addEdgeMap(mapname, emptr, def_val))
152                {
153                  abortion=1;
154                }
155
156              //add it to the list of the displayable maps
157              //furthermore it is done by signals
158              //mytab.registerNewEdgeMap(mapname);
159
160              //display it
161              //gdc.changeEdgeText(mapname);
162            }
163          else //!edge.get_active()
164            {
165              //create the new map
166              Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mytab.mapstorage.graph);
167
168              std::stack<double> polishstack;
169 
170              for(NodeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
171                {
172                  for(int i=0;i<(int)polishform.size();i++)
173                    {
174                      double op1, op2;
175                      bool operation=true;
176                      switch(polishform[i])
177                        {
178                        case '+':
179                        case '-':
180                        case '/':
181                        case '*':
182                          op1=polishstack.top();
183                          polishstack.pop();
184                          op2=polishstack.top();
185                          polishstack.pop();
186                          break;
187                        default:
188                          std::map< std::string,Graph::NodeMap<double> * > nms=mytab.mapstorage.nodemap_storage;
189                          bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
190                          if(itisvar)
191                            {
192                              polishstack.push( (*(mytab.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
193                            }
194                          else
195                            {
196                              polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
197                            }
198                          operation=false;
199                          break;
200                        }
201                      if(operation)
202                        {
203                          double res;
204                          switch(polishform[i])
205                            {
206                            case '+':
207                              res=op1+op2;
208                              break;
209                            case '-':
210                              res=op2-op1;
211                              break;
212                            case '/':
213                              res=op2/op1;
214                              break;
215                            case '*':
216                              res=op1*op2;
217                              break;
218                            default:
219                              std::cout << "How could we get here?" << std::endl;
220                              break;
221                            }
222                          polishstack.push(res);
223                        }
224                    }
225                  (*emptr)[k]=polishstack.top();
226                }
227
228              //if addition was not successful addNodeMap returns one.
229              //cause can be that there is already a map named like the new one
230              if(mytab.mapstorage.addNodeMap(mapname,emptr, def_val))
231                {
232                  abortion=1;
233                }
234
235              //add it to the list of the displayable maps
236              //furthermore it is done by signals
237              //mytab.registerNewNodeMap(mapname);
238
239              //display it
240              //gdc.changeNodeText(mapname);
241            }
242          if(!abortion)
243            {
244              name.set_text("");
245              default_value.set_text("0");
246              edge.show();
247              node.show();
248              hide();
249            }
250        }
251    }
252}
253
254
255std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
256{
257  bool valid_entry=true;
258
259  std::map<std::string, int> str2i;
260
261  std::string command;
262
263  std::string variable;
264
265  char index='a';
266
267  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
268    {
269      switch(rawcommand[i])
270        {
271        case '+':
272        case '-':
273        case '*':
274        case '/':
275        case ')':
276        case '(':
277          if(!variable.empty())
278            {
279              valid_entry=validVariable(variable, itisedge);
280              ch2var[index]=variable;
281              command+=index;
282              index++;
283              variable.erase(0,variable.size());         
284            }
285          command+=rawcommand[i];
286          break;
287        default:
288          variable+=rawcommand[i];
289          break;
290        }
291    }
292
293  if(!variable.empty()&&valid_entry)
294    {
295      valid_entry=validVariable(variable, itisedge);
296      ch2var[index]=variable;
297      command+=index;
298      index++;
299      variable.erase(0,variable.size());         
300    }
301
302  if(valid_entry)
303    {
304      unsigned int pr=10000;
305      bool prevmult=false;
306      unsigned int prev_change=pr;
307      unsigned int prev_br=pr;
308      int counter=0;
309      std::string comm_nobr="";
310      std::vector<unsigned int> p;
311      p.resize(counter+1);
312     
313      //limits
314      //6 brackets embedded
315      //100 operation in a row from the same priority
316     
317      for(int i=0;i<(int)command.size();i++)
318        {
319          bool put_in_string=true;
320          switch(command[i])
321            {
322            case '(':
323              pr=prev_br+10000;
324              prev_br=pr;
325              prevmult=false;
326              put_in_string=false;
327              break;
328            case ')':
329              pr=prev_br-10000;
330              prev_br=pr;
331              prevmult=false;
332              put_in_string=false;
333              break;
334            case '+':
335            case '-':
336              if(prevmult)
337                {
338                  pr=prev_change;
339                }
340              p[counter]=pr;
341              pr-=100;
342
343              prevmult=false;
344              break;
345            case '/':
346            case '*':
347              if(!prevmult)
348                {
349                  prev_change=pr;
350                  pr+=200;
351                  pr-=1;
352                }
353              p[counter]=pr;
354              pr-=1;
355              prevmult=true;
356              break;
357            default:
358              p[counter]=65000;
359              break;
360            }
361          if(put_in_string)
362            {
363              counter++;
364              p.resize(counter+1);
365              comm_nobr=comm_nobr+command[i];
366            }
367        }
368
369      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
370
371      std::string polishform=postOrder(root);
372
373      deleteTree(root);
374
375      return polishform;
376    }
377  return "";
378}
379
380void NewMapWin::deleteTree(NewMapWin::tree_node * node)
381{
382  if(node->left_child!=NULL)
383    {
384      deleteTree(node->left_child);
385    }
386  if(node->right_child!=NULL)
387    {
388      deleteTree(node->right_child);
389    }
390  delete node;
391}
392
393NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
394{
395  unsigned int min=p[offset];
396  int minplace=0;
397  for(int i=0;i<(int)to_tree.size();i++)
398    {
399      if(min>p[offset+i])
400        {
401          min=p[offset+i];
402          minplace=i;
403        }
404    }
405  tree_node * act_node=new tree_node;
406  act_node->ch=to_tree[minplace];
407  if(to_tree.size()>=3)
408    {
409      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
410      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
411    }
412  else
413    {
414      act_node->left_child=NULL;
415      act_node->right_child=NULL;
416    }
417  return act_node;
418}
419
420std::string NewMapWin::postOrder(tree_node * subtree)
421{
422  std::string subtree_to_string;
423  if(subtree->left_child)
424    {
425      subtree_to_string=postOrder(subtree->left_child);
426    }
427  if(subtree->right_child)
428    {
429      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
430    }
431  subtree_to_string=subtree_to_string+subtree->ch;
432  return subtree_to_string;
433}
434
435bool NewMapWin::validVariable(std::string variable, bool itisedge)
436{
437  bool cancel;
438  //is it mapname?
439  if(itisedge)
440    {
441      cancel=(mytab.mapstorage.edgemap_storage.find(variable)==mytab.mapstorage.edgemap_storage.end());
442    }
443  else
444    {
445      cancel=(mytab.mapstorage.nodemap_storage.find(variable)==mytab.mapstorage.nodemap_storage.end());
446    }
447  //maybe it is number
448  int point_num=0;
449  if(cancel)
450    {
451      cancel=false;
452      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
453        {
454          if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
455            {
456              cancel=true;
457            }
458          else
459            {
460              if(variable[j]=='.')
461                {
462                  point_num++;
463                  if(point_num>1)
464                    {
465                      cancel=true;
466                    }
467                }
468            }
469        }
470    }
471  if(cancel)
472    {
473      return false;
474    }
475  return true;
476}
Note: See TracBrowser for help on using the repository browser.