mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
add SCIP solver
This commit is contained in:
@@ -7,5 +7,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
|
||||
internal interface ICultivationItemsAccess
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
List<MaterialId> CultivationItems { get; }
|
||||
}
|
||||
@@ -59,9 +59,11 @@ internal sealed partial class InventoryService : IInventoryService
|
||||
List<ICultivationItemsAccess> cultivationItemsEntryList =
|
||||
[
|
||||
.. await metadataService.GetAvatarListAsync().ConfigureAwait(false),
|
||||
.. (await metadataService.GetWeaponListAsync().ConfigureAwait(false)).Where(weapon => weapon.Quality >= Model.Intrinsic.QualityType.QUALITY_BLUE),
|
||||
.. await metadataService.GetWeaponListAsync().ConfigureAwait(false),
|
||||
];
|
||||
|
||||
cultivationItemsEntryList = MinimalPromotionDelta.Find(cultivationItemsEntryList);
|
||||
|
||||
BatchConsumption? batchConsumption = default;
|
||||
using (IServiceScope scope = serviceScopeFactory.CreateScope())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Google.OrTools.LinearSolver;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Model.Metadata.Abstraction;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Snap.Hutao.Service.Inventory;
|
||||
|
||||
internal static class MinimalPromotionDelta
|
||||
{
|
||||
public static List<ICultivationItemsAccess> Find(List<ICultivationItemsAccess> cultivationItems)
|
||||
{
|
||||
using (Solver? solver = Solver.CreateSolver("SCIP"))
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(solver);
|
||||
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetMinimization();
|
||||
|
||||
Dictionary<ICultivationItemsAccess, Variable> itemVariableMap = [];
|
||||
foreach (ref readonly ICultivationItemsAccess item in CollectionsMarshal.AsSpan(cultivationItems))
|
||||
{
|
||||
Variable variable = solver.MakeBoolVar(item.Name);
|
||||
itemVariableMap[item] = variable;
|
||||
objective.SetCoefficient(variable, 1);
|
||||
}
|
||||
|
||||
Dictionary<MaterialId, Constraint> materialConstraintMap = [];
|
||||
foreach (ref readonly ICultivationItemsAccess item in CollectionsMarshal.AsSpan(cultivationItems))
|
||||
{
|
||||
foreach (ref readonly MaterialId materialId in CollectionsMarshal.AsSpan(item.CultivationItems))
|
||||
{
|
||||
ref Constraint? constraint = ref CollectionsMarshal.GetValueRefOrAddDefault(materialConstraintMap, materialId, out _);
|
||||
constraint ??= solver.MakeConstraint(1, double.PositiveInfinity, $"{materialId}");
|
||||
constraint.SetCoefficient(itemVariableMap[item], 1);
|
||||
}
|
||||
}
|
||||
|
||||
Solver.ResultStatus status = solver.Solve();
|
||||
HutaoException.ThrowIf(status != Solver.ResultStatus.OPTIMAL, "Unable to solve minimal item set");
|
||||
|
||||
List<ICultivationItemsAccess> results = [];
|
||||
foreach ((ICultivationItemsAccess item, Variable variable) in itemVariableMap)
|
||||
{
|
||||
if (variable.SolutionValue() > 0.5)
|
||||
{
|
||||
results.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,6 +313,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.TokenizingTextBox" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||
<PackageReference Include="Google.OrTools" Version="9.10.4067" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
Reference in New Issue
Block a user