This commit is contained in:
2026-02-08 14:50:55 +01:00
parent 5f7e9c2073
commit fa9f8d3c9c
5 changed files with 72 additions and 37 deletions

View File

@@ -20,7 +20,5 @@ struct Customer
struct Cost
{
Customer m_Customer;
Facility m_Facility;
int m_Cost;
double m_Cost;
};

View File

@@ -49,16 +49,19 @@ FileData ParseFile(const std::string& a_FileName) {
fileData.m_Customers.push_back(customer);
}
fileData.m_Costs.resize(fileData.m_Customers.size());
for (std::size_t i = 0; i < fileData.m_Customers.size(); i++) {
fileData.m_Costs[i].resize(fileData.m_Facilities.size());
}
// costs
while (getline(in, line))
{
Cost cost;
double cost;
int facilityID, customerID;
std::stringstream stream(line);
stream >> customerID >> facilityID >> cost.m_Cost;
cost.m_Customer = fileData.m_Customers[customerID - 1];
cost.m_Facility = fileData.m_Facilities[facilityID - 1];
fileData.m_Costs.push_back(cost);
stream >> customerID >> facilityID >> cost;
fileData.m_Costs[customerID - 1][facilityID - 1] = cost;
}
return fileData;

View File

@@ -7,7 +7,7 @@ struct FileData
{
std::vector<Facility> m_Facilities;
std::vector<Customer> m_Customers;
std::vector<Cost> m_Costs;
std::vector<std::vector<double>> m_Costs;
};
FileData ParseFile(const std::string& a_FileName);

View File

@@ -1,56 +1,91 @@
#include "Parser.h"
#include <fmt/format.h>
#include <iostream>
#include <kiwi/kiwi.h>
using namespace kiwi;
#include <absl/base/log_severity.h>
#include <absl/log/globals.h>
#include <absl/log/log.h>
#include <ortools/base/init_google.h>
#include <ortools/sat/cp_model.h>
#include <ortools/sat/cp_model_solver.h>
#include <chrono>
using namespace operations_research;
int main(int argc, char** argv) {
auto fileData = ParseFile("RhoneCities_100.flpb");
std::vector<Variable> y;
std::vector<std::vector<Variable>> x(fileData.m_Facilities.size());
sat::CpModelBuilder cp_model;
std::vector<sat::BoolVar> y;
std::vector<std::vector<sat::BoolVar>> x(fileData.m_Customers.size());
std::cout << "Adding variables ...\n";
Solver solver;
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
y.emplace_back(fmt::format("y_{}", j));
y.push_back(cp_model.NewBoolVar());
for (std::size_t i = 0; i < fileData.m_Customers.size(); i++) {
x[i].emplace_back(fmt::format("x_{}{}", i, j));
x[i].push_back(cp_model.NewBoolVar());
}
}
std::cout << "Adding constraints 1...\n";
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
Expression sum;
sat::LinearExpr sum;
for (std::size_t i = 0; i < fileData.m_Customers.size(); i++) {
sum = sum + fileData.m_Customers[i].m_Demand * x[i][j];
for (size_t i = 0; i < fileData.m_Customers.size(); i++) {
sum += fileData.m_Customers[i].m_Demand * x[i][j];
}
solver.addConstraint({sum <= fileData.m_Facilities[j].m_Capacity * y[j]});
cp_model.AddLessOrEqual(sum, fileData.m_Facilities[j].m_Capacity * y[j]);
}
std::cout << "Adding constraints 2...\n";
for (std::size_t i = 0; i < fileData.m_Customers.size(); i++) {
Expression sum;
cp_model.AddEquality(sat::LinearExpr::Sum(x[i]), 1);
}
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
sum = sum + x[i][j];
sat::DoubleLinearExpr obj;
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
for (size_t i = 0; i < fileData.m_Customers.size(); i++) {
auto cost = fileData.m_Costs[i][j];
obj += cost * sat::DoubleLinearExpr(x[i][j]);
}
solver.addConstraint({sum == 1});
}
std::cout << "Updating variables...\n";
solver.updateVariables();
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++)
{
std::cout << y[j].name() << "=" << y[j].value() << "\n";
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
obj += fileData.m_Facilities[j].m_Cost * sat::DoubleLinearExpr(y[j]);
}
cp_model.Minimize(obj);
std::cout << "Solving...\n";
auto start = static_cast<std::uint64_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
auto solution = sat::Solve(cp_model.Build());
auto end = static_cast<std::uint64_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
std::cout << "Done in " << end - start << "ms !" << std::endl;
std::cout << "Status : " << solution.status() << std::endl;
std::cout << "Objective : " << solution.objective_value() << "" << std::endl;
int fac_number = 0;
for (std::size_t j = 0; j < fileData.m_Facilities.size(); j++) {
bool make_fac = sat::SolutionBooleanValue(solution, y[j]);
std::cout << make_fac;
if (make_fac)
fac_number++;
}
std::cout << std::endl;
std::cout << "N=" << fac_number << std::endl;
return 0;
}

View File

@@ -1,12 +1,11 @@
add_rules("mode.debug", "mode.release")
add_requires("kiwisolver", "fmt")
-- https://github.com/Qix-/kiwi/blob/int-solver/kiwi/variable.h
add_requires("or-tools[highs=true,glpk=true]")
target("RhoneCities")
set_kind("binary")
add_packages("kiwisolver", "fmt")
add_defines("OR_PROTO_DLL=")
add_packages("or-tools")
add_files("src/*.cpp")
set_rundir(".")