def _f(m: Block): m.lmbda = Var(vertices, domain=NonNegativeReals) # 非负 m.y = Var(simplices, domain=Binary) # 二进制 m.a0 = Constraint(dimensions, rule=lambda m, d: sum(m.lmbda[v] * pointsT[d][v] for v in vertices) == input[d]) if bound == 'eq': m.a1 = Constraint(expr=output == sum(m.lmbda[v] * values[v] for v in vertices)) elif bound == 'lb': m.a1 = Constraint(expr=output <= sum(m.lmbda[v] * values[v] for v in vertices)) elif bound == 'ub': m.a1 = Constraint(expr=output >= sum(m.lmbda[v] * values[v] for v in vertices)) else: raise RuntimeError("bound值错误!bound=" + bound) m.b = Constraint(expr=sum(m.lmbda[v] for v in vertices) == 1) # generate a map from vertex index to simplex index, # which avoids an n^2 lookup when generating the # constraint vertex_to_simplex = [[] for _ in vertices] for s, simplex in enumerate(tri.simplices): for v in simplex: vertex_to_simplex[v].append(s) m.c0 = Constraint(vertices, rule=lambda m, v: m.lmbda[v] <= sum(m.y[s] for s in vertex_to_simplex[v])) m.c1 = Constraint(expr=sum(m.y[s] for s in simplices) == 1) return m
def dlog(m: Block, tri: qhull.Delaunay, values: List[float], input: List[SimpleVar] = None, output: SimpleVar = None, bound: str = 'eq', **kw): values = np.array(values).tolist() ndim = len(input) nsimplices = len(tri.simplices) npoints = len(tri.points) pointsT = list(zip(*tri.points)) # create index objects dimensions = list(range(ndim)) simplices = list(range(nsimplices)) # 跟单纯形 数量一致 vertices = list(range(npoints)) bound = bound.lower() L = int(math.ceil(math.log2(nsimplices))) L_Range = list(range(L)) vp = [0, 1, 2] # m.lmbda = Var(simplices, vp, domain=NonNegativeReals) # 非负 m.a0 = Constraint( dimensions, rule=lambda m, d: sum(m.lmbda[s, v] * pointsT[d][tri.simplices[s][v]] for s in simplices for v in vp) == input[d]) if bound == 'eq': m.a1 = Constraint(expr=output == sum( m.lmbda[s, v] * values[tri.simplices[s][v]] for s in simplices for v in vp)) elif bound == 'lb': m.a1 = Constraint( expr=output <= sum(m.lmbda[s, v] * values[tri.simplices[s][v]] for s in simplices for v in vp)) elif bound == 'ub': m.a1 = Constraint( expr=output >= sum(m.lmbda[s, v] * values[tri.simplices[s][v]] for s in simplices for v in vp)) else: raise RuntimeError("bound值错误!bound=" + bound) m.b1 = Constraint(expr=sum(m.lmbda[s, v] for s in simplices for v in vp) == 1) m.y = Var(L_Range, domain=Binary) # 二进制 m.c0 = Constraint(L_Range, rule=lambda m, l: sum(m.lmbda[s, v] for s in simplices if bin(s)[2:].zfill(L)[l] == '1' for v in vp) <= m.y[l]) m.c1 = Constraint(L_Range, rule=lambda m, l: sum(m.lmbda[s, v] for s in simplices if bin(s)[2:].zfill(L)[l] == '0' for v in vp) <= 1 - m.y[l]) return m
def cc(m: Block, tri: qhull.Delaunay, values: List[float], input: List[SimpleVar] = None, output: SimpleVar = None, bound: str = 'eq', **kw): values = np.array(values).tolist() ndim = len(input) nsimplices = len(tri.simplices) npoints = len(tri.points) pointsT = list(zip(*tri.points)) # create index objects dimensions = list(range(ndim)) simplices = list(range(nsimplices)) # 跟单纯形 数量一致 vertices = list(range(npoints)) bound = bound.lower() m.lmbda = Var(vertices, domain=NonNegativeReals) # 非负 m.y = Var(simplices, domain=Binary) # 二进制 # m.y = Var(simplices, domain=NonNegativeReals, bounds=(0, 1)) # 二进制 m.a0 = Constraint(dimensions, rule=lambda m, d: sum(m.lmbda[v] * pointsT[d][v] for v in vertices) == input[d]) if bound == 'eq': m.a1 = Constraint(expr=output == sum(m.lmbda[v] * values[v] for v in vertices)) elif bound == 'lb': m.a1 = Constraint(expr=output <= sum(m.lmbda[v] * values[v] for v in vertices)) elif bound == 'ub': m.a1 = Constraint(expr=output >= sum(m.lmbda[v] * values[v] for v in vertices)) else: raise RuntimeError("bound值错误!bound=" + bound) m.b = Constraint(expr=sum(m.lmbda[v] for v in vertices) == 1) # generate a map from vertex index to simplex index, # which avoids an n^2 lookup when generating the # constraint vertex_to_simplex = [[] for _ in vertices] for s, simplex in enumerate(tri.simplices): for v in simplex: vertex_to_simplex[v].append(s) m.c0 = Constraint( vertices, rule=lambda m, v: m.lmbda[v] <= sum(m.y[s] for s in vertex_to_simplex[v])) m.c1 = Constraint(expr=sum(m.y[s] for s in simplices) == 1) return m