#include <iostream>
#include <vector>
#define MAX_ITERATION_TIME 50
using namespace std;
struct trans {
int state;
int useFlower1;
int useFlower3;
int prob; // not include denominator 36
trans(int s, int f1, int f3, int p) {
state = s;
useFlower1 = f1;
useFlower3 = f3;
prob = p;
}
};
typedef struct trans Transition;
enum State{
FAIL = 0,
STATE2,
STATE3,
STATE4,
STATE5,
STATE6,
STATE7,
STATE_NUMBER
};
// Global Variable ...
double prob[2][STATE_NUMBER][MAX_ITERATION_TIME][MAX_ITERATION_TIME]; //buffer, state, flower1, flower3
vector<Transition> transitionMatrix[STATE_NUMBER];
int iterationTime;
int flower1Number;
int flower3Number;
// Functions
void inputSetting(int argc, char **argv) {
if (argc == 4) {
iterationTime = atoi(argv[1]);
flower1Number = atoi(argv[2]);
flower3Number = atoi(argv[3]);
} else {
cout << "Iteration time: ";
cin >> iterationTime;
if (iterationTime > MAX_ITERATION_TIME) {
cerr << "Iteration time must small than " << MAX_ITERATION_TIME << endl;
exit(1);
}
cout << "Flower 1 number: ";
cin >> flower1Number;
cout << "Flower 3 number: ";
cin >> flower3Number;
}
}
void clearProb() {
for (int i=0; i<2; i++) {
for (int j=0; j<STATE_NUMBER; j++) {
for (int k=0; k<MAX_ITERATION_TIME; k++) {
for (int l=0; l<MAX_ITERATION_TIME; l++) {
prob[i][j][k][l] = 0;
}
}
}
}
}
void copyAndClearProb() {
for (int state = 0; state < STATE_NUMBER; state++) {
for (int flower1 = 0; flower1 < iterationTime; flower1++) {
for (int flower3 = 0; flower3 < iterationTime; flower3++) {
prob[0][state][flower1][flower3] = prob[1][state][flower1][flower3];
prob[1][state][flower1][flower3] = 0;
}
}
}
}
void setInitialProb() {
double initialProb[] = {0, 2, 4, 6, 8, 10, 6};
for (int i=0; i<STATE_NUMBER; i++) {
prob[0][i][0][0] = initialProb[i] / 36;
}
}
void setTransitionMatrix() {
transitionMatrix[FAIL].push_back(Transition(FAIL,0,0,36));
//State 2 case
transitionMatrix[STATE2].push_back(Transition(STATE2,0,0,2));
transitionMatrix[STATE2].push_back(Transition(STATE3,0,0,4));
transitionMatrix[STATE2].push_back(Transition(STATE4,0,0,6));
transitionMatrix[STATE2].push_back(Transition(STATE5,0,0,8));
transitionMatrix[STATE2].push_back(Transition(STATE6,0,0,10));
transitionMatrix[STATE2].push_back(Transition(STATE7,0,0,6));
//State 3 case
transitionMatrix[STATE3].push_back(Transition(STATE2,1,0,1));
transitionMatrix[STATE3].push_back(Transition(STATE2,0,0,1));
transitionMatrix[STATE3].push_back(Transition(STATE3,0,0,4));
transitionMatrix[STATE3].push_back(Transition(STATE4,0,0,6));
transitionMatrix[STATE3].push_back(Transition(STATE5,0,0,8));
transitionMatrix[STATE3].push_back(Transition(STATE6,0,0,10));
transitionMatrix[STATE3].push_back(Transition(STATE7,0,0,6));
//State 4 case
transitionMatrix[STATE4].push_back(Transition(STATE2,0,0,1));
transitionMatrix[STATE4].push_back(Transition(STATE2,0,1,1));
transitionMatrix[STATE4].push_back(Transition(STATE3,0,0,2));
transitionMatrix[STATE4].push_back(Transition(STATE3,1,0,2));
transitionMatrix[STATE4].push_back(Transition(STATE4,0,0,6));
transitionMatrix[STATE4].push_back(Transition(STATE5,0,0,8));
transitionMatrix[STATE4].push_back(Transition(STATE6,0,0,10));
transitionMatrix[STATE4].push_back(Transition(STATE7,0,0,6));
//State 5 case
transitionMatrix[STATE5].push_back(Transition(STATE2,0,0,1));
transitionMatrix[STATE5].push_back(Transition(STATE2,0,1,1));
transitionMatrix[STATE5].push_back(Transition(STATE3,0,0,2));
transitionMatrix[STATE5].push_back(Transition(STATE3,0,1,2));
transitionMatrix[STATE5].push_back(Transition(STATE4,0,0,3));
transitionMatrix[STATE5].push_back(Transition(STATE4,1,0,3));
transitionMatrix[STATE5].push_back(Transition(STATE5,0,0,8));
transitionMatrix[STATE5].push_back(Transition(STATE6,0,0,10));
transitionMatrix[STATE5].push_back(Transition(STATE7,0,0,6));
//State 6 case
transitionMatrix[STATE6].push_back(Transition(FAIL,0,0,1));
transitionMatrix[STATE6].push_back(Transition(STATE2,0,0,1));
transitionMatrix[STATE6].push_back(Transition(STATE3,0,0,2));
transitionMatrix[STATE6].push_back(Transition(STATE3,0,1,2));
transitionMatrix[STATE6].push_back(Transition(STATE4,0,0,3));
transitionMatrix[STATE6].push_back(Transition(STATE4,0,1,3));
transitionMatrix[STATE6].push_back(Transition(STATE5,0,0,4));
transitionMatrix[STATE6].push_back(Transition(STATE5,1,0,4));
transitionMatrix[STATE6].push_back(Transition(STATE6,0,0,10));
transitionMatrix[STATE6].push_back(Transition(STATE7,0,0,6));
//State 7 case
transitionMatrix[STATE7].push_back(Transition(FAIL,0,0,3));
transitionMatrix[STATE7].push_back(Transition(STATE2,0,0,1));
transitionMatrix[STATE7].push_back(Transition(STATE3,0,0,2));
transitionMatrix[STATE7].push_back(Transition(STATE4,0,0,3));
transitionMatrix[STATE7].push_back(Transition(STATE4,0,1,3));
transitionMatrix[STATE7].push_back(Transition(STATE5,0,0,4));
transitionMatrix[STATE7].push_back(Transition(STATE5,0,1,4));
transitionMatrix[STATE7].push_back(Transition(STATE6,0,0,5));
transitionMatrix[STATE7].push_back(Transition(STATE6,1,0,5));
transitionMatrix[STATE7].push_back(Transition(STATE7,0,0,6));
}
void calculate() {
for (int flower1 = 0; flower1 < iterationTime; flower1++) {
for (int flower3 = 0; flower3 < iterationTime; flower3++) {
for (int state = 0; state < STATE_NUMBER; state++) {
double stateProb = prob[0][state][flower1][flower3];
for (vector<Transition>::iterator iter = transitionMatrix[state].begin();
iter != transitionMatrix[state].end(); iter++) {
double transitionProb = stateProb * (iter->prob) / 36;
//cout << transitionProb << endl;
int totalFlower1 = flower1 + (iter->useFlower1);
int totalFlower3 = flower3 + (iter->useFlower3);
int transitionState = iter->state;
if (totalFlower1 > flower1Number) { // Flower1 is none.
totalFlower1 = flower1;
totalFlower3 = flower3 + 1;
}
if (totalFlower3 > flower3Number) { // Fail..
totalFlower1 = flower1;
totalFlower3 = flower3;
transitionState = 0;
}
prob[1][transitionState][totalFlower1][totalFlower3] += transitionProb;
}
}
}
}
}
void printOutput() {
cout << "Total iteration time: " << iterationTime << endl;
cout << "The number Flower 1: " << flower1Number << endl;
cout << "The number Flower 3: " << flower3Number << endl;
double failProb = 0;
for (int i=0; i<iterationTime; i++) {
for (int j=0; j<iterationTime; j++) {
failProb += prob[0][0][i][j];
}
}
cout << "Failure probability: " << failProb << endl;
cout << "=================================================\n";
double flower1Expectation = 0, flower3Expectation = 0;
for (int state = 0; state < STATE_NUMBER; state++) {
for (int flower1 = 0; flower1 < iterationTime; flower1++) {
for (int flower3 = 0; flower3 < iterationTime; flower3++) {
flower1Expectation += prob[0][state][flower1][flower3] * flower1;
flower3Expectation += prob[0][state][flower1][flower3] * flower3;
}
}
}
double money = flower1Expectation * 200 + flower3Expectation * 600;
cout << "Expectation per one time:\n";
cout << "Flower 1 usage: " << flower1Expectation << endl;
cout << "Flower 3 usage: " << flower3Expectation << endl;
cout << "Money usage: " << money << endl;
cout << "=================================================\n";
flower1Expectation /= (1.0 - failProb);
flower3Expectation /= (1.0 - failProb);
money = flower1Expectation * 200 + flower3Expectation * 600;
cout << "Expectation per one success:\n";
cout << "Flower 1 usage: " << flower1Expectation << endl;
cout << "Flower 3 usage: " << flower3Expectation << endl;
cout << "Money usage: " << money << endl;
}
int main(int argc, char **argv) {
inputSetting(argc, argv);
clearProb();
setInitialProb();
setTransitionMatrix();
for (int i=0; i<iterationTime; i++) {
calculate();
copyAndClearProb();
}
printOutput();
return 0;
}
|