Now ILP solver picks optimal combination of two different similarities and similarity can also be calcuated using the mean of similarity instead of the comparitive value
192 lines
7.0 KiB
Python
192 lines
7.0 KiB
Python
import gurobipy as gp
|
|
from gurobipy import GRB, Model, quicksum
|
|
|
|
HYPEREDGES = {
|
|
1: ([], ['Xanthine']),
|
|
2: (['Xanthine'], ['p_{0,0}']),
|
|
3: (['Xanthine'], ['p_{0,1}']),
|
|
4: (['Xanthine'], ['p_{0,2}']),
|
|
5: (['p_{0,0}'], ['p_{0,3}']),
|
|
6: (['p_{0,0}'], ['p_{0,4}']),
|
|
7: (['p_{0,1}'], ['p_{0,3}']),
|
|
8: (['p_{0,1}'], ['p_{0,5}']),
|
|
9: (['p_{0,2}'], ['p_{0,4}']),
|
|
10: (['p_{0,2}'], ['p_{0,5}']),
|
|
11: (['p_{0,3}'], ['Caffeine']),
|
|
12: (['p_{0,4}'], ['Caffeine']),
|
|
13: (['p_{0,5}'], ['Caffeine']),
|
|
14: (['Caffeine'], []),
|
|
}
|
|
#Similyrity of Nodes NMR to Measured NMR
|
|
#Can how to add Values along a Path?
|
|
#Can you count position on path?
|
|
#Can you save spectra values to add hypergraphposition to spectrainformation?
|
|
#Compositespectra vs oredered set of spectra
|
|
VERTICES1 = {
|
|
1: ([0, 0], ['Xanthine']),
|
|
2: ([0, 0], ['p_{0,0}']),
|
|
3: ([0, 0], ['p_{0,1}']),
|
|
4: ([1, 0], ['p_{0,2}']),
|
|
5: ([0, 0], ['p_{0,3}']),
|
|
6: ([0, 0], ['p_{0,4}']),
|
|
7: ([0, 1], ['p_{0,5}']),
|
|
8: ([0, 0], ['Caffeine']),
|
|
}
|
|
|
|
#25014CX3
|
|
|
|
#03
|
|
|
|
VERTICES2 = {
|
|
1: ([0], ['Xanthine']),
|
|
2: ([0], ['p_{0,0}']),
|
|
3: ([0], ['p_{0,1}']),
|
|
4: ([1], ['p_{0,2}']),
|
|
5: ([0], ['p_{0,3}']),
|
|
6: ([0], ['p_{0,4}']),
|
|
7: ([1], ['p_{0,5}']),
|
|
8: ([0], ['Caffeine']),
|
|
}
|
|
|
|
VERTICES = ['Xanthine', 'p_{0,0}', 'p_{0,1}', 'p_{0,2}', 'p_{0,3}', 'p_{0,4}', 'p_{0,5}', 'Caffeine']
|
|
|
|
NMRLIKELYHOODS = [0.0, 0.2, 0.7, 0.1, 0.1, 0.2, 0.7, 0.0]
|
|
NMRLIKELYHOODS1 = [0.54, 0.52, 0.43, 0.62, 0.52, 0.56, 0.48, 0.5]
|
|
NMRLIKELYHOODS2 = [0.52, 0.52, 0.52, 0.61, 0.52, 0.56, 0.61, 0.59]
|
|
NMRLIKELYHOODS3 = [0.5, 0.53, 0.59, 0.59, 0.53, 0.56, 0.68, 0.62]
|
|
|
|
FIXED_FLOWS = {
|
|
1: 1,
|
|
14: 1,
|
|
}
|
|
|
|
def build_model(name, hyperedges, vertices, nmrlikelihoods1, nmrlikelihoods2, nmrlikelihoods3, excluded_support=None):
|
|
model = Model(name)
|
|
|
|
x = {e_id: model.addVar(vtype=GRB.INTEGER, lb = 0, name = f"x_{e_id}") for e_id in hyperedges}
|
|
b = {e_id: model.addVar(vtype=GRB.BINARY, name = f"b_{e_id}") for e_id in hyperedges}
|
|
n1 = model.addVars(vertices, vtype=GRB.CONTINUOUS, lb = 0.0, ub = 1.0, name = "nmr1")
|
|
n2 = model.addVars(vertices, vtype=GRB.CONTINUOUS, lb = 0.0, ub = 1.0, name = "nmr2")
|
|
n3 = model.addVars(vertices, vtype=GRB.CONTINUOUS, lb = 0.0, ub = 1.0, name = "nmr3")
|
|
c1 = model.addVars(vertices, vtype = GRB.BINARY, name = "n1_choice")
|
|
c2 = model.addVars(vertices, vtype = GRB.BINARY, name = "n2_choice")
|
|
c3 = model.addVars(vertices, vtype = GRB.BINARY, name = "n3_choice")
|
|
|
|
|
|
for v, nmr in zip(vertices, nmrlikelihoods1):
|
|
n1[v] = nmr
|
|
#print(f'Vertice: {v}, Similarity: {n1[v]}')
|
|
for v, nmr in zip(vertices, nmrlikelihoods2):
|
|
n2[v] = nmr
|
|
|
|
for v, nmr in zip(vertices, nmrlikelihoods3):
|
|
n3[v] = nmr
|
|
|
|
vertices = set(v for tails, heads in hyperedges.values() for v in tails + heads)
|
|
|
|
for v in vertices:
|
|
inflow = quicksum(x[e_id] for e_id, (_, heads) in hyperedges.items() if v in heads)
|
|
outflow = quicksum(x[e_id] for e_id, (tails, _) in hyperedges.items() if v in tails)
|
|
model.addConstr(inflow == outflow, name = f"flow_conservation_{v}")
|
|
|
|
for e_id, value in FIXED_FLOWS.items():
|
|
model.addConstr(x[e_id] == value, name = f"fixed_flow_{e_id}")
|
|
|
|
for e_id in hyperedges:
|
|
model.addGenConstrIndicator(b[e_id], 0, x[e_id] == 0, name = f"unused_implies_zero_{e_id}")
|
|
model.addConstr(x[e_id] >= b[e_id], name = f"used_implies_positive_flow_{e_id}")
|
|
|
|
reaction_path = {}
|
|
|
|
|
|
if excluded_support:
|
|
model.addConstr(quicksum(b[e_id] for e_id in excluded_support) <= len(excluded_support) - 1, name = "different_hyperedges",)
|
|
|
|
#Multiplizier den node Wert mit infow + outflow
|
|
model.ModelSense = GRB.MAXIMIZE
|
|
#Multiply with a list of binarys where only one value is one and the rest zero and not both the same position
|
|
'''
|
|
model.setObjectiveN(
|
|
quicksum(n1[v_id] * c1[v_id] for v_id in vertices if v_id != [])
|
|
+ quicksum(n3[v_id] * c3[v_id] for v_id in vertices if v_id != []),
|
|
index = 0,
|
|
priority = 2,
|
|
name = "maximize_nmr_similarity",
|
|
)
|
|
'''
|
|
|
|
#Multiply node value with infow or outflow
|
|
'''
|
|
model.setObjectiveN(
|
|
quicksum(n1[t_id[0]] * c1[t_id[0]] * x[e_id] for e_id, (_, t_id) in hyperedges.items() if t_id != [])
|
|
+quicksum(n3[t_id[0]] * c3[t_id[0]] * x[e_id] for e_id, (_, t_id) in hyperedges.items() if t_id != []),
|
|
index = 0,
|
|
priority = 2,
|
|
name = "maximize_nmr_similarity",
|
|
)
|
|
'''
|
|
|
|
#Hybrid of both above
|
|
model.setObjective(
|
|
quicksum(n1[t_id[0]] * c1[t_id[0]] * x[e_id] for e_id, (_, t_id) in hyperedges.items() if t_id != [])
|
|
+quicksum(n3[t_id[0]] * c3[t_id[0]] * x[e_id] for e_id, (_, t_id) in hyperedges.items() if t_id != []),
|
|
sense = GRB.MAXIMIZE,
|
|
)
|
|
|
|
|
|
model.addConstr(gp.quicksum(c1[v_id] for v_id in vertices) == 1)
|
|
model.addConstr(gp.quicksum(c3[v_id] for v_id in vertices) == 1)
|
|
for v_id in vertices:
|
|
model.addConstr(c1[v_id] + c3[v_id] <= 1)
|
|
|
|
model.addConstr(gp.quicksum(x[e_id] for e_id, (_, t_id) in hyperedges.items()) == 5)
|
|
''''
|
|
model.setObjectiveN(
|
|
quicksum(-1 *b[e_id] for e_id in hyperedges),
|
|
index=1,
|
|
priority=1,
|
|
name="minimize_used_hyperedges",
|
|
)
|
|
'''
|
|
|
|
return model, x, b
|
|
|
|
def positive_entries(variable_dict, threshold = 0.5):
|
|
return {e_id: var.X for e_id, var in variable_dict.items() if var.X > threshold}
|
|
|
|
def print_solution(title, flow_solution, binary_solution, hyperedges):
|
|
print(f"\n{title}:")
|
|
for e_id in sorted(flow_solution):
|
|
flow = flow_solution[e_id]
|
|
tails, heads = hyperedges[e_id]
|
|
print(f"Hyperedge {e_id}: Flow = {flow}, Tails = {tails}, Heads = {heads}")
|
|
print("\nBinary Variables:")
|
|
for e_id in sorted(binary_solution):
|
|
print(f"Binary Variable b_{e_id} = {binary_solution[e_id]}")
|
|
|
|
print(f"\nTotal flow: {sum(flow_solution.values())}")
|
|
print(f"Number of used hyperedges: {len(binary_solution)}")
|
|
|
|
def main():
|
|
model, x, b = build_model("HypergraphFlow", HYPEREDGES, VERTICES, NMRLIKELYHOODS1, NMRLIKELYHOODS2, NMRLIKELYHOODS3)
|
|
model.optimize()
|
|
if model.status != GRB.Status.OPTIMAL:
|
|
print("No optimal solution found for the first model.")
|
|
return
|
|
optimal_solution = positive_entries(x)
|
|
optimal_binary_solution = positive_entries(b)
|
|
print_solution("Optimal Solution", optimal_solution, optimal_binary_solution, HYPEREDGES)
|
|
|
|
""" excluded_support = list(optimal_binary_solution.keys())
|
|
second_model, x2, b2 = build_model("SecondBestHypergraphFlow", HYPEREDGES, excluded_support=excluded_support,)
|
|
|
|
second_model.optimize()
|
|
if second_model.status == GRB.Status.OPTIMAL:
|
|
second_solution = positive_entries(x2)
|
|
second_binary_solution = positive_entries(b2)
|
|
print_solution("Second Best Solution", second_solution, second_binary_solution, HYPEREDGES, VERTICES)
|
|
else:
|
|
print("No optimal solution found for the second best model.")
|
|
"""
|
|
if __name__ == "__main__":
|
|
main() |