Optaplanner:如何从JSON读取游戏装甲数据并根据重量&#x2B找到最佳装甲集。统计数据?
elden ring 是一个热门游戏,背后有一些有趣的理论。
有数百件装甲,武器和咒语。根据玩家&项目统计是一个有趣的实用问题。
我一直想学习如何使用约束求解器,并且似乎存在一个很好的用例!
目标:
- 给出了游戏中所有装甲的清单,以
- 找到的装甲集(头部,胸部,腿部,手臂):
- 最高的镇定
- 对于最低的重量
这是回购:
到目前为止
- 放置装甲数据
- github.com/gavinray97/elden-ring-optimizer-optaplanner/blob/master/src/src/main/resources/armor.json“ rel =“ nofollow noreferrer”>在此处 ://github.com/gavinray97/elden-ring-optimizer-optaplanner/blob/master/src/src/main/java/java/java/java/domain/armorpiece.java“ rel =“ nofollow noreferrer”
- @PlanningEntity class for a combination of armor
- Tried to write Solver, doesn' t工作
更新
设法在下面的建议之后解决了该
问题
@PlanningSolution
public class ArmorSetComboPlanningSolution {
public List<ArmorPiece> armorPieces;
public Map<Integer, List<ArmorPiece>> armorByType;
@ValueRangeProvider(id = "headRange")
@ProblemFactCollectionProperty
public List<ArmorPiece> headList;
@ValueRangeProvider(id = "chestRange")
@ProblemFactCollectionProperty
public List<ArmorPiece> chestList;
@ValueRangeProvider(id = "armsRange")
@ProblemFactCollectionProperty
public List<ArmorPiece> armsList;
@ValueRangeProvider(id = "legsRange")
@ProblemFactCollectionProperty
public List<ArmorPiece> legsList;
@PlanningEntityProperty
public ArmorSet armorSet;
@PlanningScore(bendableHardLevelsSize = 1, bendableSoftLevelsSize = 5)
BendableLongScore score;
ArmorSetComboPlanningSolution() {
}
ArmorSetComboPlanningSolution(List<ArmorPiece> armorPieces) {
this.armorPieces = armorPieces;
this.armorByType = armorPieces.stream().collect(groupingBy(ArmorPiece::armorCategoryID));
this.headList = armorByType.get(0);
this.chestList = armorByType.get(1);
this.armsList = armorByType.get(2);
this.legsList = armorByType.get(3);
// Need to initialize a starting value
this.armorSet = new ArmorSet(0L, this.headList.get(0), this.chestList.get(0), this.armsList.get(0), this.legsList.get(0));
}
}
。
public class ArmorSetEasyOptimizer implements EasyScoreCalculator<ArmorSetComboPlanningSolution, BendableLongScore> {
private final int TARGE_POISE = 61;
private final double MAX_WEIGHT = 60.64;
public ArmorSetEasyOptimizer() {
}
@Override
public BendableLongScore calculateScore(ArmorSetComboPlanningSolution solution) {
long hardScore = 0L;
ArmorSet armorSet = solution.armorSet;
if (armorSet.getTotalPoise() < TARGE_POISE) {
hardScore--;
}
if (armorSet.getTotalWeight() > MAX_WEIGHT) {
hardScore--;
}
long poiseRatio = (long) (armorSet.getTotalPoise() / (double) armorSet.getTotalWeight() * 100);
long physicalDefenseScaled = (long) (armorSet.getTotalPhysicalDefense() * 100);
long physicalDefenseToWeightRatio = (long) (physicalDefenseScaled / armorSet.getTotalWeight());
long magicDefenseScaled = (long) (armorSet.getTotalMagicDefense() * 100);
long magicDefenseToWeightRatio = (long) (magicDefenseScaled / armorSet.getTotalWeight());
return BendableLongScore.of(
new long[]{
hardScore
},
new long[]{
poiseRatio,
physicalDefenseScaled,
physicalDefenseToWeightRatio,
magicDefenseScaled,
magicDefenseToWeightRatio
}
);
}
}
我
19:02:12.707 [main] INFO org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase - Local Search phase (1) ended: time spent (10000), best score ([0]hard/[179/3540/97/2750/75]soft), score calculation speed (987500/sec), step total (4046).
19:02:12.709 [main] INFO org.optaplanner.core.impl.solver.DefaultSolver - Solving ended: time spent (10000), best score ([0]hard/[179/3540/97/2750/75]soft), score calculation speed (985624/sec), phase total (2), environment mode (REPRODUCIBLE), move thread count (NONE).
[0]hard/[179/3540/97/2750/75]soft
ArmorSet (Weight: 36.3, Poise: 65, Physical: 35.4, Phys/Weight: 0.97, Magic: 27.5, Magic/Weight: 0.75 ) [
head: Radahn Soldier Helm (Weight: 4.0, Poise: 5),
chest: Veteran's Armor (Weight: 18.9, Poise: 37),
arms: Godskin Noble Bracelets (Weight: 1.7, Poise: 1),
legs: Veteran's Greaves (Weight: 11.7, Poise: 22)
]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这有点奇怪,因为您只需要一个计划实体实例。只有一个
Armorset
对象 - 求解器将在越来越接近最佳组合时分配不同的装甲件。因此,您的简单得分计算器永远不需要进行任何循环。它只需采用单个
Armorset
的重量并保持平衡,并从中创建得分。但是,即使我认为这种用例可能是通往约束求解器的学习路径,但某种蛮力算法也可以工作 - 您的数据集并不大。更重要的是,使用详尽的算法(例如蛮力),您最终可以确保达到最佳解决方案。
(也就是说,如果您想将这些装甲套件与特定特征匹配的问题增加问题,那么它可能足够复杂,以使蛮力变得不足
。为我。 :-)我更喜欢引导您更多的游戏。
This is a bit of a strange problem, because you only need one planning entity instance. There only ever needs to be one
ArmorSet
object - and the solver will be assigning different armor pieces as it comes closer and closer to an optimal combination.Therefore your easy score calculator doesn't ever need to do any looping. It simply takes the single
ArmorSet
's weight and poise and creates a score out of it.However, even though I think that this use case may be useful as a learning path towards constraint solvers, some sort of a brute force algorithm could work as well - your data set isn't too large. More importantly, with an exhaustive algorithm such as brute force, you're eventually guaranteed to reach the optimal solution.
(That said, if you want to enhance the problem with matching these armor sets to particular character traits, then it perhaps may be complex enough for brute force to become inadequate.)
On a personal note, I attempted Elden Ring and found it too hardcore for me. :-) I prefer games that guide you a bit more.