COIN-OR::LEMON - Graph Library

source: glemon-0.x/new_map_win.cc @ 108:bf355fd6563e

gui
Last change on this file since 108:bf355fd6563e was 108:bf355fd6563e, checked in by Hegyi Péter, 14 years ago

Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.

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