new_map_win.cc
author hegyi
Wed, 28 Feb 2007 18:20:28 +0000
changeset 194 6b2b718420eb
parent 174 95872af46fc4
child 201 879e47e5b731
permissions -rw-r--r--
Header reorganising
     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 
    23 bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e)
    24 {
    25   if(e->keyval==GDK_Escape)
    26   {
    27     hide();
    28   }
    29   return true;
    30 }
    31 
    32 NewMapWin::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 
    87 void 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 
   298 std::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 
   423 void 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 
   436 NewMapWin::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 
   463 std::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 
   478 bool 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 }