COIN-OR::LEMON - Graph Library

source: glemon-0.x/new_map_win.cc @ 197:c1084e2bff10

Last change on this file since 197:c1084e2bff10 was 194:6b2b718420eb, checked in by Hegyi Péter, 17 years ago

Header reorganising

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