Ejemplo n.º 1
0
    def solve(self, k):
        self.initialize(k)
        if self.non_basic_idx == self.n + 1:
            self.logger.info('Found a fixed point.')
            self.fixed_point = 0
            triangle_vertices = self.triangle.get_all_vertices()
            for i, weight in enumerate(self.weights):
                self.fixed_point += weight * np.array(triangle_vertices[i])
            self.fixed_point = splx.SimplexPoint(self.fixed_point)
            return self.fixed_point

        cnt = 1
        while True:
            self.logger.info('Iteration {0}, Current triangle: {1}'.format(
                cnt, self.triangle.get_all_vertices()))
            self.move()
            self.pivot()
            cnt += 1
            if self.non_basic_idx == self.n + 1:
                break
        self.logger.info('Found a fixed point.')
        self.fixed_point = 0
        triangle_vertices = self.triangle.get_all_vertices()
        for i, weight in enumerate(self.weights):
            self.fixed_point += weight * np.array(triangle_vertices[i])
        self.fixed_point = splx.SimplexPoint(self.fixed_point)
        return self.fixed_point
Ejemplo n.º 2
0
    def initialize(self, k):
        b = self.b
        while True:
            x0 = splx.get_random_simplex_point(self.n)

            tmp = []
            for i, spike in enumerate(b):
                if spike >= 0:
                    continue
                tmp.append(-x0[i] / spike)
            theta = min(tmp)
            x0 = splx.SimplexPoint(x0 + theta * b)

            triangle = splx.get_covering_triangle(x0, k)
            triangle_vertices = triangle.get_all_vertices()
            L = np.zeros(shape=(self.n + 2, self.n + 1))
            for i in range(0, self.n + 1):
                L[:, i] = list(
                    np.array(self.f(splx.SimplexPoint(triangle_vertices[i]))) -
                    np.array(splx.SimplexPoint(triangle_vertices[i]))) + [1]
            d = np.array(list(b) + [1])
            d.shape = (self.n + 2, 1)
            m = np.array([0 for _ in range(0, self.n + 1)] + [1])

            L_ = np.concatenate([L, d], axis=1)
            pivot_idx = None

            for i in [self.n + 1] + list(range(0, self.n + 1)):
                sub_L_ = np.delete(np.delete(L_, i, axis=1), 0, axis=0)
                try:
                    v = np.linalg.solve(sub_L_, m[1:])
                except:
                    continue
                if all([w >= 0 for w in v]):
                    pivot_idx = i
                    if pivot_idx == self.n + 1:
                        self.slack_weight = 0
                        self.weights = v
                    else:
                        self.slack_weight = v[self.n]
                        self.weights = np.delete(list(np.insert(v, i, 0)),
                                                 self.n + 1)
                    print(self.weights)
                    break
            if pivot_idx is not None:
                break
        self.triangle = triangle
        self.non_basic_idx = pivot_idx
        self.L_ = L_
        self.L = L
        return triangle_vertices, pivot_idx
Ejemplo n.º 3
0
 def f(s: splx.SimplexPoint):
     """
     This is a rotation.
     """
     if s.n != 2:
         raise RuntimeError('dimension does not match!')
     return splx.SimplexPoint([s[1], s[2], s[0]])
Ejemplo n.º 4
0
 def f(s: splx.SimplexPoint):
     """
     For a given 2-simplex point (x0, x1, x2), this function gives (sqrt(x1), 1-sqrt(x1), 0).
     """
     if s.n != 2:
         raise RuntimeError('dimension does not match!')
     return splx.SimplexPoint([np.sqrt(s[1]), 1 - np.sqrt(s[1]), 0])
Ejemplo n.º 5
0
    def solve_traversal(self, k):
        all_triangles = splx.get_all_triangles(self.n, k)
        for triangle in all_triangles:
            triangle_vertices = triangle.get_all_vertices()
            L = np.zeros(shape=(self.n + 2, self.n + 1))
            for i in range(0, self.n + 1):
                L[:, i] = list(
                    np.array(self.f(splx.SimplexPoint(triangle_vertices[i]))) -
                    np.array(splx.SimplexPoint(triangle_vertices[i]))) + [1]
            m = np.array([0 for _ in range(0, self.n + 1)] + [1])

            sub_L = np.delete(L, 0, axis=0)
            v = np.linalg.solve(sub_L, m[1:])
            if all([c >= 0 for c in v]):
                self.logger.info('Found a fixed point.')
                fixed_point = 0
                for i, weight in enumerate(v):
                    fixed_point += weight * np.array(triangle_vertices[i])
                fixed_point = splx.SimplexPoint(fixed_point)
                print(fixed_point)
Ejemplo n.º 6
0
def f(sp: splx.SimplexPoint):
    """
    Input is a simplex point, we first transform it into a probability distribution, and treat it as I to solve the mfg.
    The return is again a simplex point.
    """
    major_stopping_dist = model.get_random_initial_dist()
    # minor_stopping_dist = model.get_random_initial_dist()
    minor_stopping_dist = utils.distribution.Distribution([
        i * model.T / model.time_num_grids
        for i in range(0, model.time_num_grids + 1)
    ], sp)

    solver = GameSolver(
        model,
        major_stopping_dist,
        minor_stopping_dist,
        num_max_iter=10,
        num_mc=1000,
        precision=0.05,
    )
    solver.update_()
    return splx.SimplexPoint(solver.minor_stopping_dist.pdf.values)
Ejemplo n.º 7
0
    def move(self):
        """
        Given the triangle and the non-basic index, move to the adjacent triangle.
        """
        self.logger.info('Moving to the next triangle...')
        U = splx.get_U(self.n)
        if self.non_basic_idx == 0:
            new_v = splx.SimplexPoint(
                np.array(self.triangle.v) +
                1 / self.triangle.k * U[:, self.triangle.permutation[0]])
            new_permutation = self.triangle.permutation[1:] + [
                self.triangle.permutation[0]
            ]
            self.triangle = splx.Triangle(new_v, new_permutation,
                                          self.triangle.k)

            self.non_basic_idx = self.n
            non_basic_vertex = splx.SimplexPoint(
                self.triangle.get_all_vertices()[self.non_basic_idx])
            l = np.array(
                list(
                    np.array(self.f(non_basic_vertex)) -
                    np.array(non_basic_vertex)) + [1])
            l.shape = (self.n + 2, 1)
            self.L = np.delete(self.L, 0, axis=1)
            self.L = np.concatenate([self.L, l], axis=1)

            self.weights = list(np.delete(self.weights, 0))
            self.weights = self.weights + [0]
        elif self.non_basic_idx == self.n:
            new_v = splx.SimplexPoint(
                np.array(self.triangle.v) -
                1 / self.triangle.k * U[:, self.triangle.permutation[-1]])
            new_permutation = [self.triangle.permutation[-1]
                               ] + self.triangle.permutation[:(
                                   len(self.triangle.permutation) - 1)]
            self.triangle = splx.Triangle(new_v, new_permutation,
                                          self.triangle.k)

            self.non_basic_idx = 0
            non_basic_vertex = splx.SimplexPoint(
                self.triangle.get_all_vertices()[self.non_basic_idx])
            l = np.array(
                list(
                    np.array(self.f(non_basic_vertex)) -
                    np.array(non_basic_vertex)) + [1])
            l.shape = (self.n + 2, 1)
            self.L = np.delete(self.L, self.n, axis=1)
            self.L = np.concatenate([l, self.L], axis=1)

            self.weights = list(np.delete(self.weights, self.n))
            self.weights = [0] + self.weights
        else:
            new_v = self.triangle.v
            new_permutation = self.triangle.permutation
            front = self.triangle.permutation[self.non_basic_idx - 1]
            back = self.triangle.permutation[self.non_basic_idx]
            new_permutation[self.non_basic_idx - 1] = back
            new_permutation[self.non_basic_idx] = front
            self.triangle = splx.Triangle(new_v, new_permutation,
                                          self.triangle.k)
            non_basic_vertex = splx.SimplexPoint(
                self.triangle.get_all_vertices()[self.non_basic_idx])
            l = list(
                np.array(self.f(non_basic_vertex)) -
                np.array(non_basic_vertex)) + [1]
            self.L[:, self.non_basic_idx] = l