我在prolog中实现了以下谓词:
roulette_wheel(EvaluatedPopulation, Result) :-
get_total_fitness(EvaluatedPopulation, Total_fitness),
random(0, Total_fitness, Target),
roulette_wheel_iteration(EvaluatedPopulation, 0, Target, Result).
roulette_wheel_iteration([[Fitness,Individual]|Tail], Counter, Target, Result) :-
CounterX is Counter + Fitness,
(CounterX >= Target) -> (Result = Individual); roulette_wheel_iteration(Tail, CounterX, Target, Result).
当试图运行它们时,它很可能失败了
| ?- roulette_wheel([[10,[1,1,1]], [20, [2,2,2]], [50, [5,5,5]]], R).
! Instantiation error in argument 2 of is/2
! goal: _114 is _117+20
以下是跟踪日志:
| ?- roulette_wheel([[10,[1,1,1]], [20, [2,2,2]], [50, [5,5,5]]], R).
1 1 Call: roulette_wheel([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_597) ?
2 2 Call: get_total_fitness([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_1183) ?
3 3 Call: get_total_fitness([[20,[2,2,2]],[50,[5,5,5]]],_1691) ?
4 4 Call: get_total_fitness([[50,[5,5,5]]],_2191) ?
5 5 Call: get_total_fitness([],_2691) ?
5 5 Exit: get_total_fitness([],0) ?
6 5 Call: _2191 is 50+0 ?
6 5 Exit: 50 is 50+0 ?
4 4 Exit: get_total_fitness([[50,[5,5,5]]],50) ?
7 4 Call: _1691 is 20+50 ?
7 4 Exit: 70 is 20+50 ?
3 3 Exit: get_total_fitness([[20,[2,2,2]],[50,[5,5,5]]],70) ?
8 3 Call: _1183 is 10+70 ?
8 3 Exit: 80 is 10+70 ?
2 2 Exit: get_total_fitness([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],80) ?
9 2 Call: random(0,80,_1190) ?
9 2 Exit: random(0,80,12) ?
10 2 Call: roulette_wheel_iteration([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],0,12,_597) ?
11 3 Call: _9340 is 0+10 ?
11 3 Call: _9340 is 0+10 ?
11 3 Exit: 10 is 0+10 ?
12 3 Call: 10>=12 ?
12 3 Fail: 10>=12 ?
13 3 Call: roulette_wheel_iteration([[20,[2,2,2]],[50,[5,5,5]]],_9340,12,_597) ?
14 4 Call: _9897 is _9340+20 ?
! Instantiation error in argument 2 of is/2
! goal: _9979 is _9982+20
14 4 Exception: _9897 is _9340+20 ?
! Instantiation error in argument 2 of is/2
! goal: _9418 is _9421+20
13 3 Exception: roulette_wheel_iteration([[20,[2,2,2]],[50,[5,5,5]]],_9340,12,_597) ?
! Instantiation error in argument 2 of is/2
! goal: _8894 is _8897+20
10 2 Exception: roulette_wheel_iteration([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],0,12,_597) ?
! Instantiation error in argument 2 of is/2
! goal: _911 is _914+20
1 1 Exception: roulette_wheel([[10,[1,1,1]],[20,[2,2,2]],[50,[5,5,5]]],_597) ?
! Instantiation error in argument 2 of is/2
! goal: _114 is _117+20
有谁能告诉我为什么会失败?
答案 0 :(得分:1)
失败是因为is
运算符不允许在右操作数中使用未实例化的变量。
在您的示例中,Counter未被实例化。我猜这个问题就说明了你使用;/2
的方式。
考虑对您的代码进行此修改:
roulette_wheel_iteration([[Fitness,Individual]|Tail], Counter, Target, Result) :-
CounterX is Counter + Fitness,
(CounterX >= Target -> (Result = Individual); roulette_wheel_iteration(Tail, CounterX, Target, Result)).