假设我有以下类别(带有可能的值):
animal: any, cat, dog
color: any, white, black, gray
gender: any, male, female
[...]
或更一般地......
category: <array of values>
(1)假设我有一组可配置的规则,如:
when animal is any, color is gray, gender is male, call x
when animal is dog, color is gray, gender is male, call y
when animal is any, color is any, gender is any, call z
[...]
(2)和一些输入值。
Q值。是否有算法根据给定的输入解决了找到匹配规则(优先考虑找到最具体的规则)的问题?
例1:
input (animal:dog, color:gray, gender:male)
它会叫“y”
例2:
input (color:gray, gender:female)
它会调用“z”
更合适的方法是根据规则构建搜索树(树的每个级别是一个类别)吗?
像:
- any animal
- any color
- any gender => z
- gray
- male => x
- dog
- gray
- male => y
有更好的方法吗?
谢谢!
答案 0 :(得分:2)
我会将规则哈希到地图中,然后用相同的哈希查找。
map[hash(animal, color, gender)] = function to call
call map[hash(inputanimal, inputcolor, inputgender)]
这将确保更快地创建规则并解析基于输入调用的正确函数。
如果规则必须完全匹配,或者落入通用any,any,any,那么它只需通过以下方式完成:
if map.contains(hash(inAnimal, inColour, inGender))
x = map[hash(inAnimal, inColour, inGender)]
else
x = map[hash(any, any, any)]
否则,如果它以输入开头并连续选择每个参数的任何规则,那么你可以这样做。
让哈希函数接受一组值。当您尝试匹配规则时,您从输入开始,然后连续切换到任何一个,直到找到匹配为止。
def key hash(array[])
...
决议程序......
input[] = {inAnimal, inColour, inGender}
function x
for(i = 0 to input.size) {
if(map.contains(hash(input)) {
x = map[hash(input)]
break
}
input[i] = any
}
call x
答案 1 :(得分:1)
正确的答案取决于你想要得到的幻想。有像Rete algorithm之类的东西。谷歌“专家系统”。我曾在拥有规则评估系统的大公司工作,但他们不会在内部编写 - 他们会购买商业套餐。
如果您的需求很简单,那么每个级别都是一个类别的搜索树就可以了。如果应用程序只有特定项目和一个通用“任何”项目,这将工作正常。如果存在多种普遍性(“哺乳动物”,“脊椎动物”,“动物”),它就会变得更加强硬。
如果速度是一个问题,但内存使用不是,那么你也可以尝试hashtables-of-hashtables方法。哈希表中的每个条目都是键值对。在顶级哈希表中,键是顶级类别:“dog”,“cat”,“any”。该值是另一个哈希表。在二级哈希表中,键是颜色,值是另一个哈希表。等等。最深的哈希表的值包含函数指针,闭包或编程语言提供的任何动态调用方法。
答案 2 :(得分:1)
我首先给所有变量一个唯一值(数组位置)
动物:任何= 0; cat = 1; dog = 2
性别:任何= 0;男= 1;女= 2
颜色:任何= 0;白= 1;黑色= 2;灰色= 3;
然后我会给每个可能的组合赋予一个查找值。
Animal-| ANY | cat | dog |
-------------------------------------------------------------
Gender-| any | male |female| any | male |female| any | male |female|
=============================================================
Color-any | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
-------------------------------------------------------------
white | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
-------------------------------------------------------------
black | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
-------------------------------------------------------------
gray | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 |
=============================================================
每个查找值可以通过以下方式计算:
(Animal * number of animals) + Gender + (Color * number of animals * number of sexes)
或在以下情况下: 动物是任何,(0) 颜色是灰色的,(3) 性别是男性,(1)
(Animal * number of animals) + Sex + (Color * number of animals * number of sexes)
( 0 * 3 ) + 1 + ( 3 * 3 * 3 )
(0 * 3) + 1 + (3 * 3 * 3)
0 + 1 + 27 = 28 (the lookup value from the grid above)
28表示调用X.
所以在你的程序中:
计算你的价值 将该值与已知案例进行比较
if Value in (1,2,8,13,14,15,21,28) then X
if value in (3,4,5,23,24,26,34,35,36) then Y
if value in (0,9,12,16,17,22,25) then Z
显然,这些值实际上可以存储在配置文件中,因此您可以在不重新编译的情况下更改逻辑。
答案 3 :(得分:1)
具有以下修改的决策树将起作用:
在递归遍历时,遍历'value'和'any'并跟踪每个解决方案中的任何数字,返回最小的'any'的
def遍历(values,level,tree,anyCount): 如果树是一片叶子: return(appr_func,anyCount)
v1 = None
if values[level] in tree:
v1 = traverse(values, level+1, tree[values[level]]], anyCount)
v2 = None
if 'any' in tree:
v2 = traverse(values, level+1, tree['any'], anyCount+1)
if v1!=None:
if v2!=None:
if v1[1]<v2[1]:
return v1
else:
return v2
else:
return v1
elif v2!=None:
return v2
else:
return None
答案 4 :(得分:1)
您几乎可以直接将其转换为scala代码。
惯用法,你会使用动物,猫,狗 - 在scala中使用大写字母,但是为了符合你的例子,我在这里离开了惯例之路:
abstract sealed class animal () {}
object cat extends animal () {}
object dog extends animal {}
abstract sealed class color () {}
object white extends color {}
object black extends color {}
object gray extends color {}
abstract sealed case class gender () {}
object male extends gender {}
object female extends gender {}
def input (a: Option[animal], c: Option[color], g: Option[gender]) = (a, c, g) match {
case (Some (dog), Some (gray), Some (male)) => println ("y called without freedom")
case (_, Some (gray), Some (male)) => println ("x called with animal" + a)
case (_, _, _ ) => println ("z called with anmimal: " + a + "\tcolor: " + c + "\tgender: " + g)
}
input (Some (dog), Some (gray), Some (male))
input (None, Some (gray), Some (female))
结果:
y called without freedom
x called with animal: None
您必须注意“输入”方法中的排序。具体方法必须在非特定方法之前。
在某些情况下,根据您的描述,您无法做出决定该做什么,但您必须先决定哪个测试首先出现:
(a, c, _)
(_, c, g)
(a, _, g)
所有人都有1个打开案例。如果没有别的,(a,c,g)可以匹配任何一个,但只匹配第一个。
您必须提供一般情况(_,_,_),但如果没有意义,可能会抛出错误。