COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/new_map_win.cc @ 1884:9c061834b33b

Last change on this file since 1884:9c061834b33b was 1884:9c061834b33b, checked in by Hegyi Péter, 14 years ago

In algorithm window maps can be selected and reated through MapSelector? widget.

File size: 9.9 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              //delete emptr;
164            }
165          else //!edge.get_active()
166            {
167              //create the new map
168              Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mytab.mapstorage.graph);
169
170              std::stack<double> polishstack;
171 
172              for(NodeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
173                {
174                  for(int i=0;i<(int)polishform.size();i++)
175                    {
176                      double op1, op2;
177                      bool operation=true;
178                      switch(polishform[i])
179                        {
180                        case '+':
181                        case '-':
182                        case '/':
183                        case '*':
184                          op1=polishstack.top();
185                          polishstack.pop();
186                          op2=polishstack.top();
187                          polishstack.pop();
188                          break;
189                        default:
190                          std::map< std::string,Graph::NodeMap<double> * > nms=mytab.mapstorage.nodemap_storage;
191                          bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
192                          if(itisvar)
193                            {
194                              polishstack.push( (*(mytab.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
195                            }
196                          else
197                            {
198                              polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
199                            }
200                          operation=false;
201                          break;
202                        }
203                      if(operation)
204                        {
205                          double res;
206                          switch(polishform[i])
207                            {
208                            case '+':
209                              res=op1+op2;
210                              break;
211                            case '-':
212                              res=op2-op1;
213                              break;
214                            case '/':
215                              res=op2/op1;
216                              break;
217                            case '*':
218                              res=op1*op2;
219                              break;
220                            default:
221                              std::cout << "How could we get here?" << std::endl;
222                              break;
223                            }
224                          polishstack.push(res);
225                        }
226                    }
227                  (*emptr)[k]=polishstack.top();
228                }
229
230              //if addition was not successful addNodeMap returns one.
231              //cause can be that there is already a map named like the new one
232              if(mytab.mapstorage.addNodeMap(mapname,emptr, def_val))
233                {
234                  abortion=1;
235                }
236
237              //add it to the list of the displayable maps
238              //furthermore it is done by signals
239              //mytab.registerNewNodeMap(mapname);
240
241              //display it
242              //gdc.changeNodeText(mapname);
243
244              //delete emptr;
245            }
246          if(!abortion)
247            {
248              name.set_text("");
249              default_value.set_text("0");
250              edge.show();
251              node.show();
252              hide();
253            }
254        }
255    }
256}
257
258
259std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
260{
261  bool valid_entry=true;
262
263  std::map<std::string, int> str2i;
264
265  std::string command;
266
267  std::string variable;
268
269  char index='a';
270
271  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
272    {
273      switch(rawcommand[i])
274        {
275        case '+':
276        case '-':
277        case '*':
278        case '/':
279        case ')':
280        case '(':
281          if(!variable.empty())
282            {
283              valid_entry=validVariable(variable, itisedge);
284              ch2var[index]=variable;
285              command+=index;
286              index++;
287              variable.erase(0,variable.size());         
288            }
289          command+=rawcommand[i];
290          break;
291        default:
292          variable+=rawcommand[i];
293          break;
294        }
295    }
296
297  if(!variable.empty()&&valid_entry)
298    {
299      valid_entry=validVariable(variable, itisedge);
300      ch2var[index]=variable;
301      command+=index;
302      index++;
303      variable.erase(0,variable.size());         
304    }
305
306  if(valid_entry)
307    {
308      unsigned int pr=10000;
309      bool prevmult=false;
310      unsigned int prev_change=pr;
311      unsigned int prev_br=pr;
312      int counter=0;
313      std::string comm_nobr="";
314      std::vector<unsigned int> p;
315      p.resize(counter+1);
316     
317      //limits
318      //6 brackets embedded
319      //100 operation in a row from the same priority
320     
321      for(int i=0;i<(int)command.size();i++)
322        {
323          bool put_in_string=true;
324          switch(command[i])
325            {
326            case '(':
327              pr=prev_br+10000;
328              prev_br=pr;
329              prevmult=false;
330              put_in_string=false;
331              break;
332            case ')':
333              pr=prev_br-10000;
334              prev_br=pr;
335              prevmult=false;
336              put_in_string=false;
337              break;
338            case '+':
339            case '-':
340              if(prevmult)
341                {
342                  pr=prev_change;
343                }
344              p[counter]=pr;
345              pr-=100;
346
347              prevmult=false;
348              break;
349            case '/':
350            case '*':
351              if(!prevmult)
352                {
353                  prev_change=pr;
354                  pr+=200;
355                  pr-=1;
356                }
357              p[counter]=pr;
358              pr-=1;
359              prevmult=true;
360              break;
361            default:
362              p[counter]=65000;
363              break;
364            }
365          if(put_in_string)
366            {
367              counter++;
368              p.resize(counter+1);
369              comm_nobr=comm_nobr+command[i];
370            }
371        }
372
373      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
374
375      std::string polishform=postOrder(root);
376
377      return polishform;
378    }
379  return "";
380}
381
382NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
383{
384  unsigned int min=p[offset];
385  int minplace=0;
386  for(int i=0;i<(int)to_tree.size();i++)
387    {
388      if(min>p[offset+i])
389        {
390          min=p[offset+i];
391          minplace=i;
392        }
393    }
394  tree_node * act_node=new tree_node;
395  act_node->ch=to_tree[minplace];
396  if(to_tree.size()>=3)
397    {
398      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
399      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
400    }
401  else
402    {
403      act_node->left_child=NULL;
404      act_node->right_child=NULL;
405    }
406  return act_node;
407}
408
409std::string NewMapWin::postOrder(tree_node * subtree)
410{
411  std::string subtree_to_string;
412  if(subtree->left_child)
413    {
414      subtree_to_string=postOrder(subtree->left_child);
415    }
416  if(subtree->right_child)
417    {
418      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
419    }
420  subtree_to_string=subtree_to_string+subtree->ch;
421  return subtree_to_string;
422}
423
424bool NewMapWin::validVariable(std::string variable, bool itisedge)
425{
426  bool cancel;
427  //is it mapname?
428  if(itisedge)
429    {
430      cancel=(mytab.mapstorage.edgemap_storage.find(variable)==mytab.mapstorage.edgemap_storage.end());
431    }
432  else
433    {
434      cancel=(mytab.mapstorage.nodemap_storage.find(variable)==mytab.mapstorage.nodemap_storage.end());
435    }
436  //maybe it is number
437  int point_num=0;
438  if(cancel)
439    {
440      cancel=false;
441      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
442        {
443          if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
444            {
445              cancel=true;
446            }
447          else
448            {
449              if(variable[j]=='.')
450                {
451                  point_num++;
452                  if(point_num>1)
453                    {
454                      cancel=true;
455                    }
456                }
457            }
458        }
459    }
460  if(cancel)
461    {
462      return false;
463    }
464  return true;
465}
Note: See TracBrowser for help on using the repository browser.