Skip to content
Pasqal Documentation

Analyzing QUBO solutions

import torch
from qubosolver.qubo_analyzer import QUBOAnalyzer
from qubosolver.data import QUBOSolution
num_bitstrings=100
bit_length=3
costs = torch.randint(1, 20, (2**bit_length,), dtype=torch.float)
bitstrings = torch.randint(0, 2, (num_bitstrings, bit_length))
bitstrings,counts=bitstrings.unique(dim=0,return_counts=True)
solution1 = QUBOSolution(bitstrings, costs, counts)
bitstrings = torch.randint(0, 2, (num_bitstrings, bit_length))
bitstrings,counts=bitstrings.unique(dim=0,return_counts=True)
solution2 = QUBOSolution(bitstrings, costs, counts)
# Create the analyzer with our two solutions
analyzer = QUBOAnalyzer([solution1, solution2], labels=["sol1", "sol2"])
df = analyzer.df
print("Combined DataFrame:")
print(df)
filtered_cost_df = analyzer.filter_by_cost(max_cost=10)
print("DataFrame after filtering by cost (<10):")
print(filtered_cost_df)
# Filter by percentage: keep top 10% (lowest cost) bitstrings per solution
filtered_percent_df = analyzer.filter_by_percentage(column="probs",order="descending",top_percent=0.1)
print("DataFrame after filtering by top 10% (by cost):")
filtered_percent_df
# Filter by probability: choose a threshold (here 0.4, for example)
# (Probabilities are computed from counts for each solution.)
filtered_prob_df = analyzer.filter_by_probability(min_probability=0.01)
print("DataFrame after filtering by probability:")
print(filtered_prob_df)
avg_cost_df = analyzer.average_cost()
print("Average cost for all bitstrings per solution:")
print(avg_cost_df)
print('------------------------------------------------')
avg_cost_df = analyzer.average_cost(0.5)
print("Average cost for top 50% bitstrings per solution:")
print(avg_cost_df)
print('------------------------------------------------')
avg_cost_df = analyzer.average_cost(0.1)
print("Average cost for top 10% bitstrings per solution:")
print(avg_cost_df)
print('------------------------------------------------')
avg_cost_df = analyzer.average_cost(0.01)
print("Average cost for top 1% bitstrings per solution:")
print(avg_cost_df)
best_bit_df = analyzer.best_bitstrings()
print("Best bitstring per solution:")
print(best_bit_df)
df_with_gaps = analyzer.calculate_gaps(opt_cost=10)
print("DataFrame after calculating gaps (opt_cost=10):")
print(df_with_gaps)
# Filter by percentage: keep top 10% (lowest cost) bitstrings per solution
filtered_percent_df = analyzer.filter_by_percentage(column="gaps",top_percent=0.1)
print("DataFrame after filtering by top 10% (by cost):")
print(filtered_percent_df)
plot1 = analyzer.plot(
x_axis="bitstrings",
y_axis="probs",
sort_by="probs",
sort_order="ascending",
context="notebook"
)
plot2 = analyzer.plot(
x_axis="costs",
y_axis="probs",
sort_by="costs",
sort_order="ascending",
context="notebook"
)
plot2 = analyzer.plot(
x_axis="costs",
y_axis="probs",
sort_by="costs",
sort_order="ascending",
probability_threshold=0.1,
context="notebook"
)
plot2 = analyzer.plot(
x_axis="costs",
y_axis="probs",
sort_by="costs",
sort_order="ascending",
cost_threshold=11,
context="notebook"
)
plot2 = analyzer.plot(
x_axis="costs",
y_axis="probs",
sort_by="costs",
sort_order="ascending",
top_percent=0.1,
context="notebook"
)
plot2 = analyzer.plot(
x_axis="costs",
y_axis="probs",
sort_by="costs",
sort_order="ascending",
labels=['sol1'],
context="notebook"
)
# Create a new solution with different bitstrings and costs
bitstrings = torch.randint(0, 2, (5, bit_length))
bitstrings,counts=bitstrings.unique(dim=0,return_counts=True)
costs = torch.randint(1, 20, (len(bitstrings),), dtype=torch.float)
solution3 = QUBOSolution(bitstrings, costs, counts)
# Create the analyzer with our three solutions
analyzer = QUBOAnalyzer([solution1, solution2, solution3], labels=["sol1", "sol2", "sol3"])
# Compare the solutions
analyzer.compare_qubo_solutions(["sol1", "sol3"])
print("\n -------------------------------------- \n")
analyzer.compare_qubo_solutions(["sol1", "sol2"])