所以我已经解决了这个问题一段时间了...... 我想用clpfd库解决Prolog中的这个优化问题: 想象一下,公司有几个他们想要实施的措施,每个措施都会对某些标准产生影响并定义成本。该公司有一个限制buget。 例如,一系列措施:(每项措施的5个标准) [[id,cost,[每个标准的影响列表(1,2,3,4,5)从0到100],平均影响],......]
measure(1, 100, [50,50,50,60,50]).
这是一个例子,我创建一个具有平均影响的度量列表列表......
我需要的是一种方法,它将检查我是否可以加入总预算低于预算的措施,并寻找最佳措施来改善对所有标准的影响。
以下是小型数据库的代码和示例:
measure(1, 100, [100,90,100,100,100]).
measure(2, 10, [50,70,80,80,80]).
measure(3, 200, [50,50,50,100,20]).
measure(4, 80, [100, 100,100,100,100]).
输入将是:
strategy([0.2,0.2,0.2,0.2,0.2],190).
我想要的解决方案是:措施[4]。因为平均影响较高且成本低于预算。但我继续得到第一个解决方案
strategy(Priorities, Budget):-
sumlist(Priorities, 1.0),
length(Priorities, 5),
setof([Id, Cost, Criteria], measure(Id, Cost, Criteria), List),
length(List, MaxLength),
%List of usable measures (Cost < Budget)
setof([Id, Cost, Criteria, Impact], (measure(Id, Cost, Criteria), Cost < Budget, sum_prod(Criteria, Priorities, Impact)), MeasuresList),
TotalImpact in 0 .. 100,
Length in 1 .. MaxLength,
length(Measures, Length),
domain(Measures, 1, MaxLength),
all_different(Measures),
write('Length: '), write(Length), nl,
checkMeasures(Measures, MeasuresList, Budget, TotalImpact),
labeling(maximize(TotalImpact), Measures),
write('TotalImpact: '), write(TotalImpact), nl,
write('Measures: '), write(Measures).
checkMeasures(Measures, MeasuresList, Budget, TotalImpact) :-
measuresClause(Measures, MeasuresList, 0, Budget, 0, TotalImpact).
measuresClause([Id|Rest], MeasuresList, TotalSpent,
Budget, ImpactSum, TotalImpact):-
ImpactSum == 0,
member([Id, Cost, _, Impact], MeasuresList),
I is round(Impact),
Aux #= I + ImpactSum,
Sum #= Aux,
TotalBudget #= Cost + TotalSpent,
measuresClause(Rest, MeasuresList, TotalBudget, Budget, Sum, TotalImpact).
measuresClause([Id|Rest], MeasuresList, TotalSpent,
Budget, ImpactSum, TotalImpact) :-
member([Id, Cost, _, Impact], MeasuresList),
I is round(Impact),
Aux #= I + ImpactSum,
Sum #= Aux/2,
TotalBudget #= Cost + TotalSpent,
measuresClause(Rest, MeasuresList, TotalBudget, Budget, Sum, TotalImpact).
measuresClause([], _, TotalSpent, Budget, ImpactSum, TotalImpact) :-
TotalSpent #=< Budget,
TotalImpact #= ImpactSum.
我试过这样做:
labeling([max(TotalImpact),time_out(30000,_), all], Measures),
但我刚收到第一个结果