COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/new_map_win.cc @ 1814:0f02ced2e2ba

Last change on this file since 1814:0f02ced2e2ba was 1814:0f02ced2e2ba, checked in by Hegyi Péter, 18 years ago

As initial value of a new map expression with ()+-/* operators can be given. These operators work on numbers, or on maps. If maps are given, then the new value for a given graph element will be calculated using the value from the given maps that belong to that graph element.

File size: 10.0 KB
RevLine 
[1593]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, GraphDisplayerCanvas & grdispc):gdc(grdispc),node("Create NodeMap"),edge("Create EdgeMap")
13{
14  set_title(title);
15  set_default_size(200, 50);
16
17  signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed));
18
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  (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
42  (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
43
44  vbox.pack_start(*table);
45
46  //OK button
47  button=new Gtk::Button("OK");
48
49  button->signal_clicked().connect
50    (
51     sigc::mem_fun(*this, &NewMapWin::buttonPressed)
52    );
53
54
55  vbox.pack_start(*button);
56
57  add(vbox);
58
59  show_all_children();
60
61}
62
[1737]63void NewMapWin::showByPreChoose(bool itisedge)
64{
65  if(itisedge)
66    {
67      edge.set_active();
68    }
69  else
70    {
71      node.set_active();
72    }
73  node.hide();
74  edge.hide();
75  show();
76}
77
[1593]78void NewMapWin::buttonPressed()
79{
[1814]80  double def_val=0;
[1593]81
[1814]82  //get and formulate text
[1593]83  std::string def_val_str=default_value.get_text();
[1814]84  std::string polishform=string2Polishform(def_val_str,edge.get_active());
[1593]85
[1814]86  //get name of text
[1593]87  std::string mapname=name.get_text();
88
[1814]89  if(!mapname.empty()&&!polishform.empty())
[1593]90    {
[1597]91      int abortion=0;
[1593]92      if(edge.get_active())
93        {
[1814]94          //create the new map
95          Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (gdc.mapstorage.graph);
96
97          std::stack<double> polishstack;
98 
99          for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
100            {
101              for(int i=0;i<(int)polishform.size();i++)
102                {
103                  double op1, op2;
104                  bool operation=true;
105                  switch(polishform[i])
106                    {
107                    case '+':
108                    case '-':
109                    case '/':
110                    case '*':
111                      op1=polishstack.top();
112                      polishstack.pop();
113                      op2=polishstack.top();
114                      polishstack.pop();
115                      break;
116                    default:
117                      //substitute variable
118                      std::map< std::string,Graph::EdgeMap<double> * > ems=gdc.mapstorage.edgemap_storage;
119                      bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
120                      if(itisvar)
121                        {
122                          polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
123                        }
124                      else
125                        {
126                          char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
127                          for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
128                            {
129                              def_val_ch[j]=ch2var[ polishform[i] ][j];
130                            }
131                          polishstack.push(atof(def_val_ch));
132                        }
133                      operation=false;
134                      break;
135                    }
136                  if(operation)
137                    {
138                      double res;
139                      switch(polishform[i])
140                        {
141                        case '+':
142                          res=op1+op2;
143                          break;
144                        case '-':
145                          res=op2-op1;
146                          break;
147                        case '/':
148                          res=op2/op1;
149                          break;
150                        case '*':
151                          res=op1*op2;
152                          break;
153                        default:
154                          std::cout << "How could we get here?" << std::endl;
155                          break;
156                        }
157                      polishstack.push(res);
158                    }
159                }
160              (*emptr)[k]=polishstack.top();
161            }
162
163          //if addition was not successful addEdgeMap returns one.
164          //cause can be that there is already a map named like the new one
165          if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
166            {
167              abortion=1;
168            }
169
170          //add it to the list of the displayable maps
171          gdc.mapwin.registerNewEdgeMap(mapname);
172
173          //display it
174          gdc.changeEdgeText(mapname);
[1593]175        }
[1814]176      else //!edge.get_active()
[1593]177        {
[1814]178          //create the new map
179          Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (gdc.mapstorage.graph);
180
181          std::stack<double> polishstack;
182 
183          for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
184            {
185              for(int i=0;i<(int)polishform.size();i++)
186                {
187                  double op1, op2;
188                  bool operation=true;
189                  switch(polishform[i])
190                    {
191                    case '+':
192                    case '-':
193                    case '/':
194                    case '*':
195                      op1=polishstack.top();
196                      polishstack.pop();
197                      op2=polishstack.top();
198                      polishstack.pop();
199                      break;
200                    default:
201                      std::map< std::string,Graph::NodeMap<double> * > nms=gdc.mapstorage.nodemap_storage;
202                      bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
203                      if(itisvar)
204                        {
205                          polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
206                        }
207                      else
208                        {
209                          char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
210                          for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
211                            {
212                              def_val_ch[j]=ch2var[ polishform[i] ][j];
213                            }
214                          polishstack.push(atof(def_val_ch));
215                        }
216                      operation=false;
217                      break;
218                    }
219                  if(operation)
220                    {
221                      double res;
222                      switch(polishform[i])
223                        {
224                        case '+':
225                          res=op1+op2;
226                          break;
227                        case '-':
228                          res=op2-op1;
229                          break;
230                        case '/':
231                          res=op2/op1;
232                          break;
233                        case '*':
234                          res=op1*op2;
235                          break;
236                        default:
237                          std::cout << "How could we get here?" << std::endl;
238                          break;
239                        }
240                      polishstack.push(res);
241                    }
242                }
243              (*emptr)[k]=polishstack.top();
244            }
245
246          //if addition was not successful addNodeMap returns one.
247          //cause can be that there is already a map named like the new one
248          if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
249            {
250              abortion=1;
251            }
252
253          //add it to the list of the displayable maps
254          gdc.mapwin.registerNewNodeMap(mapname);
255
256          //display it
257          gdc.changeNodeText(mapname);
[1593]258        }
[1597]259      if(!abortion)
260        {
261          name.set_text("");
262          default_value.set_text("0");
[1737]263          edge.show();
264          node.show();
[1597]265          hide();
266        }
[1593]267    }
268}
269
[1814]270std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
271{
272  bool valid_entry=true;
273
274  std::map<std::string, int> str2i;
275
276  std::string command;
277
278  std::string variable;
279
280  char index='a';
281
282  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
283    {
284      switch(rawcommand[i])
285        {
286        case '+':
287        case '-':
288        case '*':
289        case '/':
290        case ')':
291        case '(':
292          if(!variable.empty())
293            {
294              valid_entry=validVariable(variable, itisedge);
295              ch2var[index]=variable;
296              command+=index;
297              index++;
298              variable.erase(0,variable.size());         
299            }
300          command+=rawcommand[i];
301          break;
302        default:
303          variable+=rawcommand[i];
304          break;
305        }
306    }
307
308  if(!variable.empty()&&valid_entry)
309    {
310      valid_entry=validVariable(variable, itisedge);
311      ch2var[index]=variable;
312      command+=index;
313      index++;
314      variable.erase(0,variable.size());         
315    }
316
317  if(valid_entry)
318    {
319      unsigned int pr=10000;
320      bool prevmult=false;
321      unsigned int prev_change;
322      unsigned int prev_br=10000;
323      int counter=0;
324      std::string comm_nobr="";
325      std::vector<unsigned int> p;
326      p.resize(counter+1);
327     
328      //limits
329      //6 brackets embedded
330      //100 operation in a row from the same priority
331     
332      for(int i=0;i<(int)command.size();i++)
333        {
334          bool put_in_string=true;
335          switch(command[i])
336            {
337            case '(':
338              pr=prev_br+10000;
339              prev_br=pr;
340              prevmult=false;
341              put_in_string=false;
342              break;
343            case ')':
344              pr=prev_br-10000;
345              prev_br=pr;
346              prevmult=false;
347              put_in_string=false;
348              break;
349            case '+':
350            case '-':
351              if(prevmult)
352                {
353                  pr=prev_change;
354                }
355              p[counter]=pr;
356              pr-=100;
357
358              prevmult=false;
359              break;
360            case '/':
361            case '*':
362              if(!prevmult)
363                {
364                  prev_change=pr;
365                  pr+=200;
366                  pr-=1;
367                }
368              p[counter]=pr;
369              pr-=1;
370              prevmult=true;
371              break;
372            default:
373              p[counter]=65000;
374              break;
375            }
376          if(put_in_string)
377            {
378              counter++;
379              p.resize(counter+1);
380              comm_nobr=comm_nobr+command[i];
381            }
382        }
383
384      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
385
386      std::string polishform=postOrder(root);
387
388      return polishform;
389    }
390  return "";
391}
392
393NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
394{
395  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=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
442    }
443  else
444    {
445      cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.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.