コード例 #1
0
    def construct(self):
        a = "a"
        b = "b"
        c = "c"
        d = "d"
        preferences = {a: [b, c, d], b: [c, d, a], c: [d, b, a], d: [a, b, c]}
        T = PreferenceTable(preferences, center=[-3.5, 0, 0])
        C = Cycle([a, b, c, a], [b, c, d, b], center=[3, 0, 0])

        self.play(*T.create())
        self.play(*T.propose(a, b), *T.propose(b, c), *T.propose(c, d))
        self.play(*T.accept_proposal(a, b), *T.accept_proposal(b, c),
                  *T.accept_proposal(c, d))
        self.wait()
        self.play(*C.create())
        self.play(*C.accept(0, 1))
        self.play(*C.reject(0, 1))
        self.wait()
        # for anim in C.create_from_table(T):
        #     self.play(anim)
        #     self.wait(2)

        # self.play(*C.cut_first_prefs(T))
        # self.wait(2)
        # self.play(*C.accept_second_prefs(T))
        # self.wait(2)
        # self.play(*C.uncreate())

        self.wait(2)
コード例 #2
0
    def construct(self):
        title = Text("Preference Cycles:")
        self.play(Create(title))
        self.wait(1)
        self.play(ApplyMethod(title.shift, 3 * UP))
        self.wait(1)
        definition = Tex("A sequence of players $a_1, a_2, \ldots, a_r$", color=WHITE).scale(0.8).shift(1.9 * UP)
        self.play(Create(definition))
        self.wait(1)
        cycle = Cycle(["$a_1$", "$a_2$", "$a_3$", "$a_4$", "$a_5$", "$a_1$"], ["$b_1$", "$b_2$", "$b_3$", "$b_4$", "$b_5$", "$b_1$"], center=[0,-0.5,0])
        self.play(*[Create(a) for a in cycle.A_mobs[:-1]])
        definition2 = Tex("with first preferences $b_1, b_2, \ldots, b_r$", color=WHITE).scale(0.8).shift(1.4 * UP)
        self.play(Create(definition2))
        self.wait(1)
        self.play(*[Create(b) for b in cycle.B_mobs[:-1]])
        
        first_pref_arrows = [arrow for i,arrow in enumerate(cycle.arrows[:-2]) if i % 2 == 0]
        second_pref_arrows = [arrow for i,arrow in enumerate(cycle.arrows[:-2]) if i % 2 == 1]

        self.play(*[Create(ar.curr_arrow()) for ar in first_pref_arrows])
        self.wait(2)
        definition3 = Tex("where the second favorite of $a_i$ is $b_{i+1},$", color=WHITE).scale(0.8).shift(2.4 * DOWN)
        self.play(Create(definition3))
        self.wait(1)
        self.play(*[Create(ar.curr_arrow()) for ar in second_pref_arrows])
        self.wait(2)
        definition4 = Tex("wrapping around for $a_r$ and $a_1$.", color=WHITE).scale(0.8).shift(2.9 * DOWN)
        self.play(Create(definition4))
        self.play(Create(cycle.A_mobs[-1]), Create(cycle.B_mobs[-1]))
        self.play(Create(cycle.arrows[-2].curr_arrow()), Create(cycle.arrows[-1].curr_arrow()))
        self.wait(5)

        self.play(*[Uncreate(d) for d in (definition, definition2, definition3, definition4)])
        self.wait(1)

        elimination = Tex("We \\emph{eliminate} the cycle by having $b_1$ reject $a_1$.", color=WHITE).scale(0.8).shift(1.5 * UP)
        self.play(Create(elimination))
        self.wait(1)

        self.play(*(cycle.reject(0,0) + cycle.reject(5,5)))
        self.wait(1)

        elimination2 = Tex("Each $b_i$ has $a_i$ as its least favorite, so it rejects", color=WHITE).scale(0.8).shift(2.4 * DOWN)
        self.play(Create(elimination2))
        elimination3 = Tex("$a_i$ to match with $a_{i-1}$.", color=WHITE).scale(0.8).shift(2.9 * DOWN)
        self.play(Create(elimination3))
        self.wait(1)

        for i in range(5):
            self.play(*cycle.reject(i+1,i+1))
            self.play(*cycle.accept(i,i+1))

        self.wait(5)
コード例 #3
0
    def construct(self):
        why_text = Tex("Why we can remove cycles")
        self.play(Write(why_text))

        self.play(ApplyMethod(why_text.shift, UP * 3.5))

        lemma1 = r"""
            \begin{align*} \text{Lemma 1: }&\text{in any stable $M$ 
            in the reduced table,}\\
            &a_i\text{ and }b_i \text{ are matched either}\\
            &\text{for all }i \text{ or for no }i\end{align*}"""
        
        lemma1 = Tex(lemma1).next_to(why_text, DOWN * 2)
        self.play(Write(lemma1))

        def math_list(base, start, end):
            return [
                "$" + base + "_" + str(i) + "$"
                for i in range(start, end)
            ]

        As = math_list("a", 1, 5) + ["$a_1$"]
        Bs = math_list("b", 1, 5) + ["$b_1$"]
        
        c = Cycle(As, Bs, center = DOWN * 1.5)
        self.play(*c.create())
        self.wait(1)

        say_text = Tex("Let $b_3$ reject $a_3$") \
                      .next_to(lemma1, DOWN * 2) \
                      .shift(LEFT * 3)
    
        self.play(Write(say_text))

        next_text = Tex("$a_3$ proposes to $b_4$") \
                      .next_to(lemma1, DOWN * 2)   \
                      .shift(RIGHT * 3)
        self.wait(1)
        
        self.play(*c.reject(2, 2))

        self.wait(1)
        self.play(Write(next_text))
        
        self.play(*c.accept(2, 3))
        self.play(*c.reject(3, 3))
        self.play(*c.accept(3, 4))
        self.play(*(c.reject(4, 4) + c.reject(0, 0)))
        self.play(*c.accept(0, 1))
        self.play(*c.reject(1, 1))
        self.play(*c.accept(1, 2))

        self.play(*(c.uncreate()))
        self.wait(1)

        thus_text = Tex(r"""Thus if any $a_i$ is not matched with its $b_i$\\
                then no $a_i$ can match with its $b_i$""") \
                .next_to(lemma1, DOWN * 6)
        
        self.play(Write(thus_text))

        self.wait(1)            
        
        self.play(*[
            Uncreate(m) for m in
            [thus_text, next_text, say_text]
        ])

        
        
        shift_amt = 15
        
        let_m = Tex(r"""
        Let $M$ be a stable matching where each $a_i$ is matched\\
        with its $b_i$. Let $M'$ be the same matching, but each\\
        $a_i$ is matched with its second choice $b_{i+1}$
        """).next_to(why_text, DOWN * 2).shift(RIGHT * shift_amt)

        self.add(let_m)

        self.play(*[
            ApplyMethod(t.shift, LEFT * shift_amt)
            for t in [lemma1, let_m]
        ])

        lemma2 = Tex("Lemma 2: $M'$ is stable if $M$ is stable") \
                    .next_to(let_m, DOWN * 2)

        self.play(Write(lemma2))        

        self.wait()

        As = ["$a_k$", ""]
        Bs = ["$b_k$", "$b_{k+1}$"]
        
        c = Cycle(As, Bs, center = DOWN * 1.5)

        c.reject(0, 0)
        c.accept(0, 1)

        mobjs = c.get_all_mobjs()
        mobjs.pop(2)

        self.play(*[
            Create(m)
            for m in mobjs
        ])

        b_better_text = Tex(r"Each $b_i$ is better\\ off in $M'$ than $M$") \
                           .shift(LEFT * 4 + DOWN)

        self.play(Write(b_better_text))

        a_happy_text = Tex(r"$a_k$ can only prefer \\"+\
                           r"$b_k$ to its current match\\" +\
                           r"but $b_k$ is happier with\\" +\
                           r"$a_{k-1}$, so $M'$ is\\" +\
                           r"stable here") \
                        .shift(RIGHT * 4 + DOWN * 2)

        self.play(Write(a_happy_text))

        self.play(*[
            Uncreate(m)
            for m in mobjs + [b_better_text, a_happy_text]
        ])

        continue_m = Tex(r"Thus $M$ stable $\Rightarrow$ $M'$ stable,\\" +\
                         r"so if there exists a stable matching, we\\" +\
                         r"can find it by proceeding with $M'$ and\\" +\
                         r"eliminating our cycle") \
                         .shift(DOWN * 1.5)

        self.play(Write(continue_m))
        self.wait(2)
        
        self.play(*[
            ApplyMethod(t.shift, RIGHT * shift_amt)
            for t in [lemma1, let_m]
        ] + [
            Uncreate(m)
            for m in [continue_m]
        ] + [
            ApplyMethod(t.shift, DOWN * 0.8)
            for t in [lemma2]
        ])

        plus = TextMobject("+").shift(UP * 0.5)
        
        impl = TextMobject("$\\Leftarrow$") \
               .rotate_in_place(PI/2).shift(DOWN)
        self.play(Create(impl), Create(plus))
        self.wait(1)

        final = Tex(r"We can always eliminate cycles without\\"\
                    r"changing the result").next_to(impl, DOWN)
        self.play(Write(final))
        self.wait(2)