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