]> Some of my projects - graph.git/commitdiff
Add "combinatorics library".
authorAPTX <marek321@gmail.com>
Thu, 15 Dec 2011 20:20:53 +0000 (21:20 +0100)
committerAPTX <marek321@gmail.com>
Thu, 15 Dec 2011 20:20:53 +0000 (21:20 +0100)
combination.h [new file with mode: 0644]

diff --git a/combination.h b/combination.h
new file mode 100644 (file)
index 0000000..630f6a2
--- /dev/null
@@ -0,0 +1,375 @@
+//=======================================================
+// combination.h
+// Description : Template class to find combinations
+//=======================================================
+// Copyright 2003 - 2006 Wong Shao Voon
+// No warranty, implied or expressed, is included.
+// Author is not liable for any type of loss through 
+// the use of this source code. Use it at your own risk!
+//=======================================================
+
+
+#ifndef __COMBINATION_H__
+#define __COMBINATION_H__
+
+
+namespace stdcomb
+{
+
+// Non recursive template function
+template <class BidIt>
+
+inline bool next_combination(BidIt n_begin, BidIt n_end,
+BidIt r_begin, BidIt r_end)
+{
+  
+  bool boolmarked=false;
+  BidIt r_marked;
+  
+  BidIt n_it1=n_end;
+  --n_it1;
+  
+  
+  BidIt tmp_r_end=r_end;
+  --tmp_r_end;
+  
+  for(BidIt r_it1=tmp_r_end; r_it1!=r_begin || r_it1==r_begin; --r_it1,--n_it1)
+  {
+    if(*r_it1==*n_it1 )
+    {
+      if(r_it1!=r_begin) //to ensure not at the start of r sequence
+      {
+        boolmarked=true;
+        r_marked=(--r_it1);
+        ++r_it1;//add it back again 
+        continue;
+      }
+      else // it means it is at the start the sequence, so return false
+        return false;      
+    }
+    else //if(*r_it1!=*n_it1 )
+    {
+      //marked code
+      if(boolmarked==true)
+      {
+        //for loop to find which marked is in the first sequence
+        BidIt n_marked;//mark in first sequence
+        for (BidIt n_it2=n_begin;n_it2!=n_end;++n_it2)
+          if(*r_marked==*n_it2) {n_marked=n_it2;break;}
+      
+    
+        BidIt n_it3=++n_marked;    
+        for  (BidIt r_it2=r_marked;r_it2!=r_end;++r_it2,++n_it3)
+        {
+          *r_it2=*n_it3;
+        }
+        return true;
+      }
+      for(BidIt n_it4=n_begin; n_it4!=n_end; ++n_it4)
+        if(*r_it1==*n_it4)
+        {
+          *r_it1=*(++n_it4);
+          return true;           
+        }
+    }
+  }  
+
+  return true;//will never reach here    
+}
+
+// Non recursive template function with Pred
+template <class BidIt, class Prediate>
+
+inline bool next_combination(
+       BidIt n_begin, 
+       BidIt n_end,
+       BidIt r_begin, 
+       BidIt r_end,
+       Prediate Equal)
+{
+  
+  bool boolmarked=false;
+  BidIt r_marked;
+  
+  BidIt n_it1=n_end;
+  --n_it1;
+  
+  
+  BidIt tmp_r_end=r_end;
+  --tmp_r_end;
+  
+  for(BidIt r_it1=tmp_r_end; r_it1!=r_begin || r_it1==r_begin; --r_it1,--n_it1)
+  {
+    if( Equal( *r_it1, *n_it1) )
+    {
+      if(r_it1!=r_begin) //to ensure not at the start of r sequence
+      {
+        boolmarked=true;
+        r_marked=(--r_it1);
+        ++r_it1;//add it back again 
+        continue;
+      }
+      else // it means it is at the start the sequence, so return false
+        return false;      
+    }
+    else //if(*r_it1!=*n_it1 )
+    {
+      //marked code
+      if(boolmarked==true)
+      {
+        //for loop to find which marked is in the first sequence
+        BidIt n_marked;//mark in first sequence
+        for (BidIt n_it2=n_begin;n_it2!=n_end;++n_it2)
+          if( Equal( *r_marked, *n_it2) ) {n_marked=n_it2;break;}
+      
+    
+        BidIt n_it3=++n_marked;    
+        for  (BidIt r_it2=r_marked;r_it2!=r_end;++r_it2,++n_it3)
+        {
+          *r_it2=*n_it3;
+        }
+        return true;
+      }
+      for(BidIt n_it4=n_begin; n_it4!=n_end; ++n_it4)
+        if( Equal(*r_it1, *n_it4) )
+        {
+          *r_it1=*(++n_it4);
+          return true;           
+        }
+    }
+  }  
+
+  return true;//will never reach here    
+}
+
+
+// Non recursive template function
+template <class BidIt>
+
+inline bool prev_combination(BidIt n_begin, BidIt n_end,
+BidIt r_begin, BidIt r_end)
+{
+  
+  bool boolsame=false;
+  BidIt marked;//for r
+  BidIt r_marked;
+  BidIt n_marked;
+  
+
+  BidIt tmp_n_end=n_end;
+  --tmp_n_end;
+  
+  BidIt r_it1=r_end;
+  --r_it1;
+  
+  for(BidIt n_it1=tmp_n_end; n_it1!=n_begin || n_it1==n_begin ; --n_it1)
+  {
+    if(*r_it1==*n_it1)
+    {
+      r_marked=r_it1;
+      n_marked=n_it1;
+      break;
+    }
+  }  
+  
+  BidIt n_it2=n_marked;
+
+
+  BidIt tmp_r_end=r_end;
+  --tmp_r_end;
+  
+  for(BidIt r_it2=r_marked; r_it2!=r_begin || r_it2==r_begin; --r_it2,--n_it2)
+  {
+    if(*r_it2==*n_it2 )
+    {
+      if(r_it2==r_begin&& !(*r_it2==*n_begin) )
+      {
+        for(BidIt n_it3=n_begin;n_it3!=n_end;++n_it3)
+        {
+          if(*r_it2==*n_it3)
+          {
+            marked=r_it2;
+            *r_it2=*(--n_it3);
+            
+            BidIt n_it4=n_end;
+            --n_it4;
+            for(BidIt r_it3=tmp_r_end; (r_it3!=r_begin || r_it3==r_begin) &&r_it3!=marked; --r_it3,--n_it4)
+            {
+              *r_it3=*n_it4;              
+            }
+            return true;
+          }
+        }
+      }
+      else if(r_it2==r_begin&&*r_it2==*n_begin)
+      {
+        return false;//no more previous combination; 
+      }
+    }
+    else //if(*r_it2!=*n_it2 )
+    {
+      ++r_it2;
+      marked=r_it2;
+      for(BidIt n_it5=n_begin;n_it5!=n_end;++n_it5)
+      {
+        if(*r_it2==*n_it5)
+        {
+          *r_it2=*(--n_it5);
+
+          BidIt n_it6=n_end;
+          --n_it6;
+          for(BidIt r_it4=tmp_r_end; (r_it4!=r_begin || r_it4==r_begin) &&r_it4!=marked; --r_it4,--n_it6)
+          {
+            *r_it4=*n_it6;              
+          }
+          return true;
+        }
+      }
+    }
+  }  
+  return false;//Will never reach here, unless error    
+}
+
+
+// Non recursive template function with Pred
+template <class BidIt, class Prediate>
+
+inline bool prev_combination(
+       BidIt n_begin, 
+       BidIt n_end,
+       BidIt r_begin, 
+       BidIt r_end,
+       Prediate Equal)
+{
+  
+  bool boolsame=false;
+  BidIt marked;//for r
+  BidIt r_marked;
+  BidIt n_marked;
+  
+
+  BidIt tmp_n_end=n_end;
+  --tmp_n_end;
+  
+  BidIt r_it1=r_end;
+  --r_it1;
+  
+  for(BidIt n_it1=tmp_n_end; n_it1!=n_begin || n_it1==n_begin ; --n_it1)
+  {
+    if( Equal(*r_it1, *n_it1) )
+    {
+      r_marked=r_it1;
+      n_marked=n_it1;
+      break;
+    }
+  }  
+  
+  BidIt n_it2=n_marked;
+
+
+  BidIt tmp_r_end=r_end;
+  --tmp_r_end;
+  
+  for(BidIt r_it2=r_marked; r_it2!=r_begin || r_it2==r_begin; --r_it2,--n_it2)
+  {
+    if( Equal(*r_it2, *n_it2) )
+    {
+      if(r_it2==r_begin&& !Equal(*r_it2, *n_begin) )
+      {
+        for(BidIt n_it3=n_begin;n_it3!=n_end;++n_it3)
+        {
+          if(Equal(*r_it2, *n_it3))
+          {
+            marked=r_it2;
+            *r_it2=*(--n_it3);
+            
+            BidIt n_it4=n_end;
+            --n_it4;
+            for(BidIt r_it3=tmp_r_end; (r_it3!=r_begin || r_it3==r_begin) &&r_it3!=marked; --r_it3,--n_it4)
+            {
+              *r_it3=*n_it4;              
+            }
+            return true;
+          }
+        }
+      }
+      else if(r_it2==r_begin&&Equal(*r_it2, *n_begin))
+      {
+        return false;//no more previous combination; 
+      }
+    }
+    else //if(*r_it2!=*n_it2 )
+    {
+      ++r_it2;
+      marked=r_it2;
+      for(BidIt n_it5=n_begin;n_it5!=n_end;++n_it5)
+      {
+        if(Equal(*r_it2, *n_it5))
+        {
+          *r_it2=*(--n_it5);
+
+          BidIt n_it6=n_end;
+          --n_it6;
+          for(BidIt r_it4=tmp_r_end; (r_it4!=r_begin || r_it4==r_begin) &&r_it4!=marked; --r_it4,--n_it6)
+          {
+            *r_it4=*n_it6;              
+          }
+          return true;
+        }
+      }
+    }
+  }  
+  return false;//Will never reach here, unless error    
+}
+
+
+// Recursive template function
+template <class RanIt, class Func>
+
+void recursive_combination(RanIt nbegin, RanIt nend, int n_column,
+                     RanIt rbegin, RanIt rend, int r_column,int loop, Func func)
+{
+       
+       int r_size=rend-rbegin;
+       
+       
+       int localloop=loop;
+       int local_n_column=n_column;
+       
+       //A different combination is out
+       if(r_column>(r_size-1))
+       {
+    func(rbegin,rend);
+    return;
+       }
+       /////////////////////////////////
+       
+       for(int i=0;i<=loop;++i)
+       {
+                               
+               RanIt it1=rbegin;
+               for(int cnt=0;cnt<r_column;++cnt)
+               {
+                 ++it1;
+               } 
+               
+               RanIt it2=nbegin;
+               for(int cnt2=0;cnt2<n_column+i;++cnt2)
+               {
+                 ++it2;
+               } 
+               
+               *it1=*it2;
+               
+               ++local_n_column;
+               
+               recursive_combination(nbegin,nend,local_n_column,
+                       rbegin,rend,r_column+1,localloop,func);
+               --localloop;
+       }
+       
+}
+
+}
+
+#endif