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.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()
 | 
					        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:
 | 
				
			||||||
 | 
					            #         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"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:
 | 
					            with open("projection.out", "a") as file:
 | 
				
			||||||
                    file.write("##################################\n"
 | 
					                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(gap)+"\n"+str(A_t)
 | 
					                            +str(A_t)+"\n")
 | 
				
			||||||
                               +"\n##################################\n")
 | 
					        if factor > 2:
 | 
				
			||||||
            if cnt%100==0:
 | 
					            print("conjecture is wrong")
 | 
				
			||||||
                print(f"#{cnt}, n={n}, max gap = {maxgap}")
 | 
					            print(str(A_t))
 | 
				
			||||||
 | 
					            exit(1)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user