2009-08-10 60 views
2

我有这种情况,我需要让用户根据给定条件的数量来定义决策。例如我的节目需要自动生成矩阵如下面给出的,有两个条件(IsMale和IsSmoker):以编程方式在C#中生成决策表?

IsMale: YES YES NO NO 
IsSmoker: YES NO YES NO 

而deicsion由用户定义的,因此任何下列的可以是有效的:

IsMale: YES YES NO NO 
IsSmoker: YES NO YES NO 
Decision: T F T F 

IsMale: YES YES NO NO 
IsSmoker: YES NO YES NO 
Decision: F F F F 

IsMale: YES YES NO NO 
IsSmoker: YES NO YES NO 
Decision: T T T T 

对于每个条件只能有两种状态,。这样的组合的总数被计算如下:

没有可能状态(S)到的没有条件(C) S上的功率^ C =总无组合

4种可能性(2^2 = 4)

Condition A T T F F 
Condition B T F T F 

8种可能性(2^3 = 8)

Condition A T T T T F F F F 
Condition B T T F F T F T F 
Condition C T F T F T T F F 

希望我已经解释了自己比原来的问题好一点。

更新: 根据Guffa给出的答案。下面是他的算法来生成不同组合的手工计算。

4 possibilities (2^2=4) 

索引= 0,(右移位0)

binary 8 4 2 1 Value 

original 0 0 0 1 1 
& 1  0 0 0 1 1 T 

original 0 0 1 0 2 
& 1  0 0 0 1 0 F 

original 0 0 1 1 3 
& 1  0 0 0 1 1 T 

original 0 1 0 0 4 
& 1  0 0 0 1 0 F 

索引= 1,(右移1)

binary 8 4 2 1 Value 
original 0 0 0 1 1 
shift 0 0 0 0 0 
& 1  0 0 0 1 0 F 

original 0 0 1 0 2 
shift 0 0 0 1 1 
& 1  0 0 0 1 1 T 

original 0 0 1 1 3 
shift 0 0 0 1 1 
& 1  0 0 0 1 1 T 

original 0 1 0 0 4 
shift 0 0 1 0 2 
& 1  0 0 0 1 0 F 

组合:

Condition 1: TFTF 
Condition 2: FTTF 
+0

看来你应该在每一列上都有一些标签,这样才有意义? – ScottS 2009-08-10 07:00:22

+0

Martin Fowler写的关于决策表:http://martinfowler.com/dslwip/DecisionTable.html – 2009-08-10 07:12:21

+0

在手计算结果的原始值应该介于0到3而不是1到4. – Guffa 2009-08-10 09:01:52

回答

4

输出矩阵是相当简单:

int conditions = 3; 
for (int c = 0; c < conditions; c++) { 
    Console.WriteLine(
     "Condition {0} : {1}", 
     (char)('A' + c), 
     new String(
      Enumerable.Range(0, (1 << conditions)) 
      .Select(n => "TF"[(n >> c) & 1]) 
      .ToArray() 
     ) 
    ); 
} 

所以,你想用它做什么?

+0

在8小时的编程之后,一些人可以跳到救援中,stackoverflow是非常有用的。 – Jeff 2009-08-10 07:27:40

+0

我认为你的代码中存在一个错误,你应该从(1 <<条件)中删除 - 1 – Jeff 2009-08-10 07:38:46

+0

是的,你是对的。Range方法的第二个参数是一个计数,而不是结束索引 – Guffa 2009-08-10 07:49:55

0

我想我知道你在说什么。如果你的条件不那么糟糕,你可以说:

 
if (A && B && C) { 
    return X; 
} 
if (!A && B && C) { 
    return Y; 
} 

哦等等!我想你正在寻找所有不同的条件组合!你想排列!如果你只有二进制,先生,每个组合可以通过计数找到。

我不太明白: 它看起来像

 
State   1 2 3 4 
Condition A T T F F 

+0

我不确定数学术语,但是“哦,等等!我认为你正在寻找所有不同的条件组合!“这就是我想要做的。” – Jeff 2009-08-10 07:23:16

0

除非我错过了某些东西,在问题定义中缺少某些东西。您已经定义了可能的输入范围,这肯定很容易产生?

Condition A T T F F 
Condition B T F T F 
Decision  T F F F 

输出需要定义,不能推导出来。作为一个例子,我填写了一个AND。

看起来像我的glib“容易产生”是问题。不是递归解决方案的工作?

for (members of getListOfCombinedStates(n)) 
    print theMember 

getListOfCombinedStates(int howMany) { 
    if ( n == 1) 
     return list of possible States 
    else { 
     create empty resultlist 
     for (members of getListofCombinedStates(howMany -1)) 
      for (members of listOfStates) 
       create new CombinedState by suffixing state, add to resultList 

     return resultList 
    } 

因此,对于n = 2的我们称之为getListOfCombinedStates(2),它调用getListOfCombinedStates(1),并且返回{T,F}。然后迭代{T,F},并将第一个T和它们F加到产生{T,T}和{T,F},然后{F,T}和{F,F} 。

我希望很清楚getListOfCombinedStates(3)将如何调用getListOfCombinedStates(2)并生成所需的值。

0

我不知道你的意思,但也许这是你在找什么:

我做了一些小的调整,因为你的第二个例子是不是与第一个一致的;并取消了位(我用0代替了F,用1代替了T),以显示我的观点。

Condition A 0 0 0 0 1 1 1 1 
Condition B 0 0 1 1 0 0 1 1 
Condition C 0 1 0 1 0 1 0 1 

现在,观察每个的模式,想想二进制数)。

(我希望你的想法。)

2

由于DJNA在他/她的答案已经提到的,你缺少的判定的输出。例如,如果您有一个接受两个输入的运算符(例如:和,或运算符),则必须尝试输入所有可能的输入。对于一个简单的运算符来说很简单,因为只有四个可能的输入,但对于更复杂的运算符,您将必须生成2^n个可能的输入来计算所有可能的输出。

我建议在n个布尔变量的数组中做这件事,在这里你翻转位来获得2^n个可能的输入,然后用生成的输入数组测试你的运算符并打印结果。

生成数组的一种简单方法是创建一个循环,在该循环中将一个变量从0增加到2^n-1,然后将数字转换为二进制。你会得到这样的事情:(对于n = 3):

0: 0 0 0 
1: 0 0 1 
2: 0 1 0 
3: 0 1 1 
4: 1 0 0 
5: 1 0 1 
6: 1 1 0 
7: 1 1 1 

希望这有助于!