testing my 2 factor conjecture
This commit is contained in:
102
Kmn_2factor.sage
Normal file
102
Kmn_2factor.sage
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# cogirth-packing gap of projections of graphic matroids
|
||||||
|
# see if gap(projection) <= 2 * gap(graph)
|
||||||
|
|
||||||
|
from sage.all import *
|
||||||
|
from sage.matroids.all import *
|
||||||
|
from sage.graphs.all import *
|
||||||
|
import gurobipy as gp
|
||||||
|
from gurobipy import GRB
|
||||||
|
from fractions import Fraction
|
||||||
|
|
||||||
|
env = gp.Env(empty=True)
|
||||||
|
env.setParam("OutputFlag",0)
|
||||||
|
env.start()
|
||||||
|
|
||||||
|
def representative_vectors(m, n):
|
||||||
|
for w1 in range(m+1):
|
||||||
|
for w2 in range(n+1):
|
||||||
|
v = [0]*(m+n)
|
||||||
|
v[:w1] = [1]*w1
|
||||||
|
v[m:m+w2] = [1]*w2
|
||||||
|
yield tuple(v)
|
||||||
|
|
||||||
|
def base_hittingset_with_callback(M, integral=true):
|
||||||
|
# model
|
||||||
|
model = gp.Model("mip1",env=env)
|
||||||
|
groundset = M.groundset()
|
||||||
|
x = dict()
|
||||||
|
if integral:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.BINARY)
|
||||||
|
else:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.CONTINUOUS,lb=0,ub=1)
|
||||||
|
# there is no lazy constraint for LP...
|
||||||
|
for B in M.bases():
|
||||||
|
model.addConstr(gp.quicksum([x[e] for e in B])>=1)
|
||||||
|
model.setObjective(gp.quicksum([x[e] for e in groundset]), GRB.MINIMIZE)
|
||||||
|
# callback
|
||||||
|
def callback_func(model, where):
|
||||||
|
if integral and where == GRB.Callback.MIPSOL:
|
||||||
|
sol_values = {key: model.cbGetSolution(var)
|
||||||
|
for key, var in x.items()}
|
||||||
|
# find min weight base in the matroid
|
||||||
|
base = frozenset()
|
||||||
|
minweight=0
|
||||||
|
for e in sorted(groundset, key=lambda ee: sol_values[ee]):
|
||||||
|
if M.is_independent(base.union([e])):
|
||||||
|
base=base.union([e])
|
||||||
|
minweight=minweight+sol_values[e]
|
||||||
|
if minweight < 1:
|
||||||
|
model.cbLazy(gp.quicksum([x[e] for e in base])>=1)
|
||||||
|
# solve
|
||||||
|
if integral:
|
||||||
|
model.Params.Heuristics = 0
|
||||||
|
model.Params.LazyConstraints = 1
|
||||||
|
model.optimize(callback_func)
|
||||||
|
else:
|
||||||
|
model.optimize()
|
||||||
|
return model.ObjVal
|
||||||
|
|
||||||
|
|
||||||
|
cnt=0 # actual number of instances tested
|
||||||
|
maxfactor=0
|
||||||
|
for N in range(2,10):
|
||||||
|
for M in range(N,10):
|
||||||
|
g=graphs.CompleteBipartiteGraph(N,M)
|
||||||
|
MG=Matroid(g)
|
||||||
|
mincut=base_hittingset_with_callback(MG)
|
||||||
|
treepacking=base_hittingset_with_callback(MG,integral=false)
|
||||||
|
g_gap=mincut/treepacking
|
||||||
|
A=g.incidence_matrix()
|
||||||
|
n,m = A.dimensions()
|
||||||
|
# enumerate all vectors in F_2^n with even number of 1s
|
||||||
|
m_gap=0
|
||||||
|
for v in representative_vectors(N,M):
|
||||||
|
cnt=cnt+1
|
||||||
|
v_col=matrix(v).transpose()
|
||||||
|
A_t=A.augment(v_col)
|
||||||
|
# print(A_t)
|
||||||
|
MM=Matroid(matrix=A_t,field=GF(2))/m #contract the last element
|
||||||
|
cogirth = base_hittingset_with_callback(MM,integral=true)
|
||||||
|
strength = base_hittingset_with_callback(MM,integral=false)
|
||||||
|
gap = cogirth/strength
|
||||||
|
m_gap=max(m_gap,gap)
|
||||||
|
# maxgap=max(gap,maxgap)
|
||||||
|
# if gap > maxgap:
|
||||||
|
# maxgap = gap
|
||||||
|
# print(f"find a large gap: {gap}")
|
||||||
|
# with open("projection.out", "a") as file:
|
||||||
|
# file.write("##################################\n"
|
||||||
|
# +str(gap)+"\n"+str(A_t)
|
||||||
|
# +"\n##################################\n")
|
||||||
|
factor=m_gap/g_gap
|
||||||
|
fr = lambda xx: str(Fraction(xx).limit_denominator(m))
|
||||||
|
maxfactor=max(maxfactor,factor)
|
||||||
|
print(f"K_{{{N},{M}}} graph gap = {fr(g_gap):8} projection gap = {fr(m_gap):8} factor={fr(factor):8} max={maxfactor}")
|
||||||
|
if factor >= 2:
|
||||||
|
with open("Kmn_2factor.out", "a") as file:
|
||||||
|
file.write(f"K_{{{N},{M}}} graph gap = {fr(g_gap):8} projection gap = {fr(m_gap):8} factor={fr(factor):8} max={maxfactor}\n"
|
||||||
|
+str(A_t)+"\n")
|
||||||
|
if factor > 2:
|
||||||
|
print("conjecture is wrong")
|
||||||
|
print(str(A_t))
|
||||||
|
exit(1)
|
||||||
73
cogirth_callback.sage
Normal file
73
cogirth_callback.sage
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
from sage.all import *
|
||||||
|
from sage.matroids.all import *
|
||||||
|
from sage.graphs.all import *
|
||||||
|
import gurobipy as gp
|
||||||
|
from gurobipy import GRB
|
||||||
|
|
||||||
|
env = gp.Env(empty=True)
|
||||||
|
env.setParam("OutputFlag",0)
|
||||||
|
env.start()
|
||||||
|
|
||||||
|
def base_hittingset_with_callback(M, integral=true):
|
||||||
|
# model
|
||||||
|
model = gp.Model("mip1",env=env)
|
||||||
|
groundset = M.groundset()
|
||||||
|
x = dict()
|
||||||
|
if integral:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.BINARY)
|
||||||
|
else:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.CONTINUOUS,lb=0,ub=1)
|
||||||
|
# there is no lazy constraint for LP...
|
||||||
|
for B in M.bases():
|
||||||
|
model.addConstr(gp.quicksum([x[e] for e in B])>=1)
|
||||||
|
model.setObjective(gp.quicksum([x[e] for e in groundset]), GRB.MINIMIZE)
|
||||||
|
# callback
|
||||||
|
def callback_func(model, where):
|
||||||
|
if integral and where == GRB.Callback.MIPSOL:
|
||||||
|
sol_values = {key: model.cbGetSolution(var)
|
||||||
|
for key, var in x.items()}
|
||||||
|
# find min weight base in the matroid
|
||||||
|
base = frozenset()
|
||||||
|
minweight=0
|
||||||
|
for e in sorted(groundset, key=lambda ee: sol_values[ee]):
|
||||||
|
if M.is_independent(base.union([e])):
|
||||||
|
base=base.union([e])
|
||||||
|
minweight=minweight+sol_values[e]
|
||||||
|
if minweight < 1:
|
||||||
|
model.cbLazy(gp.quicksum([x[e] for e in base])>=1)
|
||||||
|
# solve
|
||||||
|
if integral:
|
||||||
|
model.Params.Heuristics = 0
|
||||||
|
model.Params.LazyConstraints = 1
|
||||||
|
model.optimize(callback_func)
|
||||||
|
else:
|
||||||
|
model.optimize()
|
||||||
|
return model.ObjVal
|
||||||
|
|
||||||
|
# tests
|
||||||
|
if __name__ == "__main__":
|
||||||
|
def cogirthip(bases, integral=true):
|
||||||
|
model = gp.Model("mip1",env=env)
|
||||||
|
groundset=frozenset()
|
||||||
|
for B in bases: groundset=groundset|frozenset(B)
|
||||||
|
x = dict()
|
||||||
|
if integral:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.BINARY)
|
||||||
|
else:
|
||||||
|
for e in groundset: x[e]=model.addVar(vtype=GRB.CONTINUOUS,lb=0)
|
||||||
|
model.setObjective(gp.quicksum([x[e] for e in groundset]), GRB.MINIMIZE)
|
||||||
|
for B in bases:
|
||||||
|
model.addConstr(gp.quicksum([x[e] for e in B])>=1)
|
||||||
|
model.optimize()
|
||||||
|
return model.ObjVal
|
||||||
|
f = lambda g: g.is_connected()
|
||||||
|
for N in range(4,10):
|
||||||
|
for g in filter(f, graphs(N)):
|
||||||
|
M=Matroid(g)
|
||||||
|
cb=base_hittingset_with_callback(M)
|
||||||
|
bf=cogirthip(M.bases())
|
||||||
|
if randint(0,100)==1:
|
||||||
|
print(f"callback:{cb}, bf:{bf}")
|
||||||
|
if abs(cb-bf) > 0.01:
|
||||||
|
print(f"callback:{cb}, bf:{bf}")
|
||||||
|
exit(1)
|
||||||
116
projection.out
116
projection.out
@@ -1,108 +1,8 @@
|
|||||||
##################################
|
n=7 , m=10 graph gap = 1 projection gap = 2 factor=2 max=2.0
|
||||||
1.0
|
[1 1 1 0 0 0 0 0 0 0 0]
|
||||||
[1 0 0 1]
|
[0 0 0 1 1 1 0 0 0 0 1]
|
||||||
[0 1 0 1]
|
[0 0 0 0 0 0 1 1 1 0 1]
|
||||||
[0 0 1 0]
|
[0 0 0 0 0 0 0 0 0 1 1]
|
||||||
[1 1 1 0]
|
[1 0 0 1 0 0 1 0 0 0 1]
|
||||||
##################################
|
[0 1 0 0 1 0 0 1 0 0 1]
|
||||||
##################################
|
[0 0 1 0 0 1 0 0 1 1 1]
|
||||||
1.3333333333333333
|
|
||||||
[1 0 0 1]
|
|
||||||
[0 1 0 1]
|
|
||||||
[0 0 1 1]
|
|
||||||
[1 1 1 1]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
1.4999999999999998
|
|
||||||
[1 0 0 0 1]
|
|
||||||
[0 1 0 0 1]
|
|
||||||
[0 0 1 0 1]
|
|
||||||
[0 0 0 1 1]
|
|
||||||
[1 1 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
1.5
|
|
||||||
[1 1 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 1]
|
|
||||||
[0 0 0 0 1 1 1]
|
|
||||||
[1 0 1 0 1 0 0]
|
|
||||||
[0 1 0 1 0 1 1]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
1.7142857142857137
|
|
||||||
[1 1 0 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 0 1]
|
|
||||||
[0 0 0 0 1 1 0 1]
|
|
||||||
[1 0 1 0 1 0 1 1]
|
|
||||||
[0 1 0 1 0 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
1.7142857142857142
|
|
||||||
[1 1 0 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 0 1]
|
|
||||||
[0 0 0 0 1 1 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1]
|
|
||||||
[1 0 1 0 1 0 0 0]
|
|
||||||
[0 1 0 1 0 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.0
|
|
||||||
[1 1 0 0 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 0 0 1]
|
|
||||||
[0 0 0 0 1 1 0 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1 1]
|
|
||||||
[1 0 1 0 1 0 1 0 0]
|
|
||||||
[0 1 0 1 0 1 0 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.1333333333333337
|
|
||||||
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1]
|
|
||||||
[0 1 0 0 0 1 0 0 0 1 1 1 0 0 0 1]
|
|
||||||
[0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 1]
|
|
||||||
[0 0 0 1 0 0 0 1 0 0 1 0 1 0 1 1]
|
|
||||||
[0 0 0 0 1 0 0 0 1 0 0 1 0 1 1 1]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.1428571428571423
|
|
||||||
[1 1 1 0 0 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 1 1 1 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1 1 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 0 0 0 1 1 1 0 0 1]
|
|
||||||
[1 0 0 1 0 0 1 0 0 1 0 0 1 0 1]
|
|
||||||
[0 1 0 0 1 0 0 1 0 0 1 0 0 1 1]
|
|
||||||
[0 0 1 0 0 1 0 0 1 0 0 1 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.1818181818181817
|
|
||||||
[1 1 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 1 1 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 0 0 1 1 0 1]
|
|
||||||
[1 0 1 0 1 0 0 0 0 0 1 1]
|
|
||||||
[0 1 0 1 0 0 1 0 1 0 0 0]
|
|
||||||
[0 0 0 0 0 1 0 1 0 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.181818181818182
|
|
||||||
[1 1 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 1 1 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 1 1 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 0 0 1 1 0 1]
|
|
||||||
[1 0 1 0 1 0 0 0 0 0 1 0]
|
|
||||||
[0 1 0 1 0 0 1 0 1 0 0 1]
|
|
||||||
[0 0 0 0 0 1 0 1 0 1 1 0]
|
|
||||||
##################################
|
|
||||||
##################################
|
|
||||||
2.4000000000000004
|
|
||||||
[1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1]
|
|
||||||
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
|
|
||||||
[1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1]
|
|
||||||
[0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1]
|
|
||||||
[0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1]
|
|
||||||
##################################
|
|
||||||
|
|||||||
@@ -1,41 +1,67 @@
|
|||||||
# cogirth-packing gap of projections of graphic matroids
|
# cogirth-packing gap of projections of graphic matroids
|
||||||
|
# see if gap(projection) <= 2 * gap(graph)
|
||||||
|
|
||||||
from sage.all import *
|
from sage.all import *
|
||||||
from sage.matroids.all import *
|
from sage.matroids.all import *
|
||||||
from sage.graphs.all import *
|
from sage.graphs.all import *
|
||||||
import gurobipy as gp
|
import gurobipy as gp
|
||||||
from gurobipy import GRB
|
from gurobipy import GRB
|
||||||
|
from fractions import Fraction
|
||||||
|
|
||||||
env = gp.Env(empty=True)
|
env = gp.Env(empty=True)
|
||||||
env.setParam("OutputFlag",0)
|
env.setParam("OutputFlag",0)
|
||||||
env.start()
|
env.start()
|
||||||
|
|
||||||
|
def base_hittingset_with_callback(M, integral=true):
|
||||||
def cogirthip(bases, integral=true):
|
# model
|
||||||
model = gp.Model("mip1",env=env)
|
model = gp.Model("mip1",env=env)
|
||||||
# model.Params.LogToConsole = 0
|
groundset = M.groundset()
|
||||||
groundset=frozenset()
|
|
||||||
for B in bases: groundset=groundset|frozenset(B)
|
|
||||||
x = dict()
|
x = dict()
|
||||||
if integral:
|
if integral:
|
||||||
for e in groundset: x[e]=model.addVar(vtype=GRB.BINARY)
|
for e in groundset: x[e]=model.addVar(vtype=GRB.BINARY)
|
||||||
else:
|
else:
|
||||||
for e in groundset: x[e]=model.addVar(vtype=GRB.CONTINUOUS,lb=0)
|
for e in groundset: x[e]=model.addVar(vtype=GRB.CONTINUOUS,lb=0,ub=1)
|
||||||
model.setObjective(gp.quicksum([x[e] for e in groundset]), GRB.MINIMIZE)
|
# there is no lazy constraint for LP...
|
||||||
for B in bases:
|
for B in M.bases():
|
||||||
model.addConstr(gp.quicksum([x[e] for e in B])>=1)
|
model.addConstr(gp.quicksum([x[e] for e in B])>=1)
|
||||||
model.optimize()
|
model.setObjective(gp.quicksum([x[e] for e in groundset]), GRB.MINIMIZE)
|
||||||
|
# callback
|
||||||
|
def callback_func(model, where):
|
||||||
|
if integral and where == GRB.Callback.MIPSOL:
|
||||||
|
sol_values = {key: model.cbGetSolution(var)
|
||||||
|
for key, var in x.items()}
|
||||||
|
# find min weight base in the matroid
|
||||||
|
base = frozenset()
|
||||||
|
minweight=0
|
||||||
|
for e in sorted(groundset, key=lambda ee: sol_values[ee]):
|
||||||
|
if M.is_independent(base.union([e])):
|
||||||
|
base=base.union([e])
|
||||||
|
minweight=minweight+sol_values[e]
|
||||||
|
if minweight < 1:
|
||||||
|
model.cbLazy(gp.quicksum([x[e] for e in base])>=1)
|
||||||
|
# solve
|
||||||
|
if integral:
|
||||||
|
model.Params.Heuristics = 0
|
||||||
|
model.Params.LazyConstraints = 1
|
||||||
|
model.optimize(callback_func)
|
||||||
|
else:
|
||||||
|
model.optimize()
|
||||||
return model.ObjVal
|
return model.ObjVal
|
||||||
|
|
||||||
|
|
||||||
cnt=0 # actual number of instances tested
|
cnt=0 # actual number of instances tested
|
||||||
maxgap=0
|
maxfactor=0
|
||||||
f = lambda g: g.is_connected()
|
f = lambda g: g.is_connected()
|
||||||
for N in range(4,10):
|
for N in range(4,10):
|
||||||
for g in filter(f, graphs(N)):
|
for g in filter(f, graphs(N)):
|
||||||
|
MG=Matroid(g)
|
||||||
|
mincut=base_hittingset_with_callback(MG)
|
||||||
|
treepacking=base_hittingset_with_callback(MG,integral=false)
|
||||||
|
g_gap=mincut/treepacking
|
||||||
A=g.incidence_matrix()
|
A=g.incidence_matrix()
|
||||||
n,m = A.dimensions()
|
n,m = A.dimensions()
|
||||||
# enumerate all vectors in F_2^n with even number of 1s
|
# enumerate all vectors in F_2^n with even number of 1s
|
||||||
|
m_gap=0
|
||||||
V = VectorSpace(GF(2), N)
|
V = VectorSpace(GF(2), N)
|
||||||
for v in filter(lambda v: v.hamming_weight() % 2 == 0 and v!=0, V):
|
for v in filter(lambda v: v.hamming_weight() % 2 == 0 and v!=0, V):
|
||||||
cnt=cnt+1
|
cnt=cnt+1
|
||||||
@@ -44,17 +70,27 @@ for N in range(4,10):
|
|||||||
# print(A_t)
|
# print(A_t)
|
||||||
M=Matroid(matrix=A_t,field=GF(2))/m #contract the last element
|
M=Matroid(matrix=A_t,field=GF(2))/m #contract the last element
|
||||||
# print(M)
|
# print(M)
|
||||||
bases=M.bases()
|
cogirth = base_hittingset_with_callback(M,integral=true)
|
||||||
strength=cogirthip(bases,integral=false)
|
strength = base_hittingset_with_callback(M,integral=false)
|
||||||
cogirth =cogirthip(bases,integral=true)
|
|
||||||
gap = cogirth/strength
|
gap = cogirth/strength
|
||||||
|
m_gap=max(m_gap,gap)
|
||||||
# maxgap=max(gap,maxgap)
|
# maxgap=max(gap,maxgap)
|
||||||
if gap > maxgap:
|
# if gap > maxgap:
|
||||||
maxgap = gap
|
# maxgap = gap
|
||||||
print(f"find a large gap: {gap}")
|
# print(f"find a large gap: {gap}")
|
||||||
with open("projection.out", "a") as file:
|
# with open("projection.out", "a") as file:
|
||||||
file.write("##################################\n"
|
# file.write("##################################\n"
|
||||||
+str(gap)+"\n"+str(A_t)
|
# +str(gap)+"\n"+str(A_t)
|
||||||
+"\n##################################\n")
|
# +"\n##################################\n")
|
||||||
if cnt%100==0:
|
factor=m_gap/g_gap
|
||||||
print(f"#{cnt}, n={n}, max gap = {maxgap}")
|
fr = lambda xx: str(Fraction(xx).limit_denominator(m))
|
||||||
|
maxfactor=max(maxfactor,factor)
|
||||||
|
print(f"n={n:<2}, m={m:<4} graph gap = {fr(g_gap):8} projection gap = {fr(m_gap):8} factor={fr(factor):8} max={maxfactor}")
|
||||||
|
if factor >= 2:
|
||||||
|
with open("projection.out", "a") as file:
|
||||||
|
file.write(f"n={n:<2}, m={m:<4} graph gap = {fr(g_gap):8} projection gap = {fr(m_gap):8} factor={fr(factor):8} max={maxfactor}\n"
|
||||||
|
+str(A_t)+"\n")
|
||||||
|
if factor > 2:
|
||||||
|
print("conjecture is wrong")
|
||||||
|
print(str(A_t))
|
||||||
|
exit(1)
|
||||||
Reference in New Issue
Block a user