mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Merge branch 'main' of github.com:Hestia-Homes/Model into mlmodel
This commit is contained in:
commit
d8c19d5382
5 changed files with 77 additions and 15 deletions
2
.idea/Model.iml
generated
2
.idea/Model.iml
generated
|
|
@ -7,7 +7,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/recommendations" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/recommendations" isTestSource="false" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.10 (simulation_system_prediction)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.10 (backend)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (simulation_system_prediction)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
|
||||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||||
<option name="version" value="3" />
|
<option name="version" value="3" />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
from mip import Model, xsum, minimize, BINARY
|
from mip import Model, xsum, minimize, BINARY, OptimizationStatus
|
||||||
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
||||||
class CostOptimiser:
|
class CostOptimiser:
|
||||||
|
|
@ -9,6 +12,7 @@ class CostOptimiser:
|
||||||
def __init__(self, components, min_gain):
|
def __init__(self, components, min_gain):
|
||||||
self.components = components
|
self.components = components
|
||||||
self.min_gain = min_gain
|
self.min_gain = min_gain
|
||||||
|
self.gain_constraint = None
|
||||||
self.m = None
|
self.m = None
|
||||||
self.variables = []
|
self.variables = []
|
||||||
self.solution = []
|
self.solution = []
|
||||||
|
|
@ -42,21 +46,51 @@ class CostOptimiser:
|
||||||
# This constrain ensures that sum of gain_ig * x_ig >= min_gain, where gain_ig represents the gain for the ith
|
# This constrain ensures that sum of gain_ig * x_ig >= min_gain, where gain_ig represents the gain for the ith
|
||||||
# component
|
# component
|
||||||
# in group g, and x_ig is the binary decision variable for the ith component in group g
|
# in group g, and x_ig is the binary decision variable for the ith component in group g
|
||||||
self.m += xsum(
|
gain_expression = xsum(
|
||||||
item['gain'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
item['gain'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
||||||
zip(group, group_vars)
|
zip(group, group_vars)
|
||||||
) >= self.min_gain
|
) >= self.min_gain
|
||||||
|
|
||||||
|
self.gain_constraint = self.m.add_constr(gain_expression)
|
||||||
|
|
||||||
# At most one item from each group
|
# At most one item from each group
|
||||||
# This constraint ensures that at most one item from each group is selected
|
# This constraint ensures that at most one item from each group is selected
|
||||||
# This is expressed by summing up the decision variables for each group and ensuring that the sum is <= 1
|
# This is expressed by summing up the decision variables for each group and ensuring that the sum is <= 1
|
||||||
for group_vars in self.variables:
|
for group_vars in self.variables:
|
||||||
self.m += xsum(var for var in group_vars) <= 1
|
self.m += xsum(var for var in group_vars) <= 1
|
||||||
|
|
||||||
|
def setup_slack(self):
|
||||||
|
|
||||||
|
# Remove the original gain constraint
|
||||||
|
self.m.remove(self.gain_constraint)
|
||||||
|
# Add slack variable
|
||||||
|
s = self.m.add_var(lb=0)
|
||||||
|
|
||||||
|
# Modify the constraint
|
||||||
|
self.m += xsum(
|
||||||
|
item['gain'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
||||||
|
zip(group, group_vars)
|
||||||
|
) + s >= self.min_gain
|
||||||
|
|
||||||
|
# Modify the objective to penalize the use of slack
|
||||||
|
penalty = 10000 # you can adjust this based on how much you want to penalize the use of slack
|
||||||
|
self.m.objective = minimize(
|
||||||
|
xsum(
|
||||||
|
component['cost'] * var for group, group_vars in zip(self.components, self.variables) for component, var
|
||||||
|
in
|
||||||
|
zip(group, group_vars)
|
||||||
|
) + penalty * s
|
||||||
|
)
|
||||||
|
|
||||||
def solve(self):
|
def solve(self):
|
||||||
# Solve the problem
|
# Solve the problem
|
||||||
self.m.optimize()
|
self.m.optimize()
|
||||||
|
|
||||||
|
if self.m.status == OptimizationStatus.INFEASIBLE:
|
||||||
|
logger.info("We have an infeasible model, setting up slack model")
|
||||||
|
self.setup_slack()
|
||||||
|
self.m.optimize()
|
||||||
|
|
||||||
self.solution = [
|
self.solution = [
|
||||||
item for group, group_vars in zip(self.components, self.variables) for item, var in zip(group, group_vars)
|
item for group, group_vars in zip(self.components, self.variables) for item, var in zip(group, group_vars)
|
||||||
if
|
if
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
from mip import Model, xsum, maximize, BINARY
|
from mip import Model, xsum, maximize, BINARY, OptimizationStatus
|
||||||
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
||||||
class GainOptimiser:
|
class GainOptimiser:
|
||||||
"""
|
"""
|
||||||
This class is used maximise gain, given a constrained cost
|
This class is used to maximise gain, given a constrained cost
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, components, max_cost):
|
def __init__(self, components, max_cost):
|
||||||
self.components = components
|
self.components = components
|
||||||
self.max_cost = max_cost
|
self.max_cost = max_cost
|
||||||
|
self.cost_constraint = None
|
||||||
self.m = None
|
self.m = None
|
||||||
self.variables = []
|
self.variables = []
|
||||||
self.solution = []
|
self.solution = []
|
||||||
|
|
||||||
self.solution_gain = None
|
self.solution_gain = None
|
||||||
self.solution_cost = None
|
self.solution_cost = None
|
||||||
|
|
||||||
|
|
@ -26,7 +29,6 @@ class GainOptimiser:
|
||||||
self.components
|
self.components
|
||||||
]
|
]
|
||||||
|
|
||||||
# Set objective
|
|
||||||
# This objective is the sum
|
# This objective is the sum
|
||||||
# gain_ig * x_ig, where gain_ig represents the gain for ith part in group g
|
# gain_ig * x_ig, where gain_ig represents the gain for ith part in group g
|
||||||
# and x_ig is the binary decision variable for the ith part in group g
|
# and x_ig is the binary decision variable for the ith part in group g
|
||||||
|
|
@ -38,33 +40,58 @@ class GainOptimiser:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add constraints
|
|
||||||
# This constrain ensures that sum of cost_ig * x_ig <= C, where cost_ig represents the cost for the ith
|
# This constrain ensures that sum of cost_ig * x_ig <= C, where cost_ig represents the cost for the ith
|
||||||
# component
|
# component
|
||||||
# in group g, and x_ig is the binary decision variable for the ith component in group g
|
# in group g, and x_ig is the binary decision variable for the ith component in group g
|
||||||
self.m += xsum(
|
cost_expression = xsum(
|
||||||
item['cost'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
item['cost'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
||||||
zip(group, group_vars)
|
zip(group, group_vars)
|
||||||
) <= self.max_cost
|
) <= self.max_cost
|
||||||
|
|
||||||
# At most one item from each group
|
self.cost_constraint = self.m.add_constr(cost_expression)
|
||||||
|
|
||||||
# This constraint ensures that at most one item from each group is selected
|
# This constraint ensures that at most one item from each group is selected
|
||||||
# This is expressed by summing up the decision variables for each group and ensuring that the sum is <= 1
|
# This is expressed by summing up the decision variables for each group and ensuring that the sum is <= 1
|
||||||
for group_vars in self.variables:
|
for group_vars in self.variables:
|
||||||
self.m += xsum(var for var in group_vars) <= 1
|
self.m += xsum(var for var in group_vars) <= 1
|
||||||
|
|
||||||
|
def setup_slack(self):
|
||||||
|
# Remove the original cost constraint
|
||||||
|
self.m.remove(self.cost_constraint)
|
||||||
|
|
||||||
|
# Add slack variable
|
||||||
|
s = self.m.add_var(lb=0)
|
||||||
|
|
||||||
|
# Modify the constraint
|
||||||
|
self.m += xsum(
|
||||||
|
item['cost'] * var for group, group_vars in zip(self.components, self.variables) for item, var in
|
||||||
|
zip(group, group_vars)
|
||||||
|
) + s <= self.max_cost
|
||||||
|
|
||||||
|
# Modify the objective to penalize the use of slack
|
||||||
|
penalty = -10000 # Negative penalty because we are maximizing
|
||||||
|
self.m.objective = maximize(
|
||||||
|
xsum(
|
||||||
|
component['gain'] * var for group, group_vars in zip(self.components, self.variables) for component, var
|
||||||
|
in
|
||||||
|
zip(group, group_vars)
|
||||||
|
) + penalty * s
|
||||||
|
)
|
||||||
|
|
||||||
def solve(self):
|
def solve(self):
|
||||||
# Solve the problem
|
# Solve the problem
|
||||||
self.m.optimize()
|
self.m.optimize()
|
||||||
|
|
||||||
|
if self.m.status == OptimizationStatus.INFEASIBLE:
|
||||||
|
logger.info("We have an infeasible model, setting up slack model")
|
||||||
|
self.setup_slack()
|
||||||
|
self.m.optimize()
|
||||||
|
|
||||||
self.solution = [
|
self.solution = [
|
||||||
item for group, group_vars in zip(self.components, self.variables) for item, var in zip(group, group_vars)
|
item for group, group_vars in zip(self.components, self.variables) for item, var in zip(group, group_vars)
|
||||||
if
|
if
|
||||||
var.x >= 0.99
|
var.x >= 0.99
|
||||||
]
|
]
|
||||||
|
|
||||||
# Get the selected items
|
|
||||||
|
|
||||||
self.solution_gain = self.m.objective.x
|
self.solution_gain = self.m.objective.x
|
||||||
self.solution_cost = sum([component['cost'] for component in self.solution])
|
self.solution_cost = sum([component['cost'] for component in self.solution])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from backend.Property import Property
|
from backend.Property import Property
|
||||||
from statistics import mean
|
from statistics import mean
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
def estimate_sap_points():
|
def estimate_sap_points():
|
||||||
|
|
@ -9,7 +10,7 @@ def estimate_sap_points():
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return 999
|
return random.sample(range(4, 12), 1)[0]
|
||||||
|
|
||||||
|
|
||||||
def r_value_per_mm_to_u_value(depth_mm: int, r_value_per_mm: float):
|
def r_value_per_mm_to_u_value(depth_mm: int, r_value_per_mm: float):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue