3

I'm sure there's a name or method for what I'm trying to achieve, but as you can judge from the somewhat vague title of this question I just don't know how to word it, and therefore am having trouble searching.

Here's what I would like to do:

I have a list of items with several possible states. For simplicity, let's call the items A, B and C and the states 0 through 5.

The States of each item can only increment by 1 during each step. Only one item may be incremented during each step. At the start of each scenario A, B and C are all 0. At the end of each scenario A, B and C are all 5.

This would be an example of the most obvious scenario. All scenarios would have the same amount of steps.

A 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 
B 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 
C 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 

I would like to iterate through every single possible "decision path". I have calculations to perform at every step, and I have values to compare for each scenario to determine which is superior. Just in case it's not already clear, here's an example of a completely random scenario, but one which would eventually be run with the desired algorithm.

A 0 0 0 0 0 0 1 1 2 3 4 5 5 5 5 5
B 0 1 2 2 3 3 3 4 4 4 4 4 4 4 5 5
C 0 0 0 1 1 2 2 2 2 2 2 2 3 4 4 5

Is there a name or common procedure for this sort of task? Not necessarily looking for a direct answer (would be a bonus), but at least some key words so I can search more effectively!

Thanks in advance.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Pat
  • 343
  • 4
  • 14

2 Answers2

2

Enumerate all possible words of length 15 with five 0, five 1, and five 2. 0 represents an increase for A, 1 represents an increase for B, 2 represents an increase for C.

#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int main(){
  int n=5;
  vector<int> u(3),v(3*n);
  for (int i = 0; i < n; i++){
    v[i] = 0; v[i+n] = 1; v[i+2*n] = 2;
  }
  do
  {
    fill(u.begin(),u.end(),0);
    for (int j = 0; j < 3*n; j++){
      for (int i = 0; i < 3; i++)
        cout << u[i] << "\t";
      cout << endl;
      u[v[j]]++;
    }
    for (int i = 0; i < 3; i++)
      cout << u[i] << "\t";
    cout << endl;
    cout << endl;
  } while (next_permutation(v.begin(),v.end()));
  return 0;
}
galath
  • 5,717
  • 10
  • 29
  • 41
  • Thank you, this seems to work well. I'll try and get it working for my particular application. – Pat Oct 22 '12 at 00:12
1

You can think of the 2D case as binomial coefficients -- imagine the a rectangle where you're trying to get from bottom left to upper right without going left or down. You can implement the counts via Pascal's triangle. Here's a picture from Wikipedia:

Pascal's Triangle

In fact, this generalizes to multinomials, which uses Pascal's simplex.

You can solve this recursively (in pseudocode):

go( a: List, list: List ) = {
  if (a.forall(_ == 0)) {
    // do magic on list
  } else {
    a.zip(1 to a.size).foreach( (number,index) => if (number > 0 ) {
      go(a.patch(index-1,Seq(number-1),1), list ++ index)
    })
  }
}
Larry
  • 4,491
  • 2
  • 24
  • 16