graphs – Unique property of a complete binary tree

I read a statement that was not clear to me and I hoped to get clarification.

He said that considering a complete binary tree with $ n> $ 2 leaves, there is an internal node such as one-third to two-thirds of all $ n $ the leaves in the tree are his descendants.

From my understanding, I know that every internal node in a complete binary tree has 2 children. That said, the whole tree has $ 2n – $ 1 nodes, which means $ n – $ 1 of them are internal nodes (no leaves).

I can offer examples from cases where this is always the case, but I do not know how to formally reason. Any help would be greatly appreciated.

merkle tree – Intuition for CheckSigHashAll's simplicity

So I downloaded Simplicity and started a REPL using cabal new-repl Simplicity. Then I activated the type apps using :set -XTypeApplications.

Consider these invocations:

> (pkwCheckSigHashAll @CommitmentRoot @() lib (Schnorr.PubKey True (read "0")) (Schnorr.Sig (read "0") (read "1")))
CommitmentRoot {commitmentRoot = Hash256 {hash256 = 
"CANr201231SO0:1183130aDC3m4u!193247eEOT194nOUS208150&2182ACK203151>"}}

> (pkwCheckSigHashAll @CommitmentRoot @() lib (Schnorr.PubKey True (read "1")) (Schnorr.Sig (read "0") (read "1")))
CommitmentRoot {commitmentRoot = Hash256 {hash256 = 
"215222oj251&134SOZ202@N161(185j2DELt156147136Nz183179EOTH166FS141F"}}

> (pkwCheckSigHashAll @CommitmentRoot @() lib (Schnorr.PubKey True (read "1")) (Schnorr.Sig (read "0") (read "0")))
CommitmentRoot {commitmentRoot = Hash256 {hash256 = 
"215222oj251&134SOZ202@N161(185j2DELt156147136Nz183179EOTH166FS141F"}}

As I understand it, the root of the commitment goes into a transaction output. Since the signature does not have to play role, the output of Haskell is generated since I modify the signature without affecting the root of the engagement. The example above seems to correspond to this intuition. Is my intuition and code example correct?

Now, I can call the same method with WitnessRoot:

> (pkwCheckSigHashAll @WitnessRoot @() lib (Schnorr.PubKey True (read "0")) (Schnorr.Sig (read "0") (read "0")))
WitnessRoot {witnessRoot = Hash256 {hash256 = 
"185FS176179b{Xc2216n240186205v208164NW\DLE193:ETBbMO211152*I%"}}

> (pkwCheckSigHashAll @WitnessRoot @() lib (Schnorr.PubKey True (read "1")) (Schnorr.Sig (read "0") (read "0")))
WitnessRoot {witnessRoot = Hash256 {hash256 = 
"240hNUL188z4ACK200ETX151DC1&Y253t152176P146186137NAKm!STXDC3182148193246172O"}}

> (pkwCheckSigHashAll @WitnessRoot @() lib (Schnorr.PubKey True (read "0")) (Schnorr.Sig (read "0") (read "1")))
WitnessRoot {witnessRoot = Hash256 {hash256 = 
"205DEL132Q245166!196178248136194aO243+145T200E129I#253F134173i243K154J"}}

Again, as I understand it, the witness's root enters the expense transaction entry. It seems that the witness's root is affected if I change my signature or public key, which is my intuition. Simplicity uses BIP-Schnorr, which does not allow the recovery of public keys. Again, is my intuition compatible with the code above?

I guess these hash values ​​contain fictitious transaction metadata such as nLocktime, embedded in the lib, correct?

Now, suppose I want to make a MAST 2-based multisig with Simplicity, what would it look like? There must be a way to dial two different calls to CheckSigHashAll. And the expense transaction should surely provide a MAST path through the script, how can I pass it to Simplicity? With oooh?

Why are so few languages ​​providing tree or graph types in their kernel?

The more I read from CS, the more trees, heaps and graphics I encounter. All languages ​​seem to incorporate linear data types such as lists and tables, and most have composite data types such as objects or structures, but for hierarchical data structures such as trees, must either roll yours every time, or look in the package. ecosystem. It is felt that in many languages, trees are second-class citizens, even though they seem fundamental to CS and that they contain many useful algorithms.

Why is it? Is it because there are too many tree variations to write a powerful generic implementation?

algorithms – Creating a priority search tree to find the number of points in the range [-inf, qx] X [qy, qy’] from a set of points sorted on the coordinates there

A priority search tree can be built on a set of points P in O (n log (n)), but if the points are sorted on the y coordinates, it takes O (n) time. I find algorithms to build the tree when the points are not sorted.

I've found a way to do this as follows:

  1. Build a TSB on the points.
    Since the points are sorted, it will take O (n) time

  2. Min-Heapify the TSB on x coordinates
    It will take time theta (n)

So the total time complexity will be O (n)

Is this a valid approach to build a priority search tree in a time O (n) ??

Same KNN result and decision tree

With a decision tree, is it possible to find a KNN classifier with exactly the same classification?

Graph Theory – Tree Path Disjoint in Pairs

Let T be a tree with 2k leaves. Prove that there is a pair in pairs
Edge-disjoint T-paths connecting the leaves in pairs.

My attempt:
Suppose, on the contrary, let $ p_i $ and $ p_j $ to be paths with an edge in common for $ i neq j $. Then, the paths overlap because they determine 4 distinct leaves. Therefore, we proved the statement. Am I correct guys or I need to change my arguments.

Bitcoin merkle tree

I'm sorry, can anyone help …

Does Bitcoin explain the falsified attack as a second pre-image attack and how is it implemented?

In addition, how does bitcoin avoid the unbalanced Merkle tree?

cordially

Get a book / menu tree programmatically

With a node ID, how do I view the outline of the book to which it belongs?

I send the book pages from one route, one variable, one route (and not the node's alias) so that the navigation block of the default book does not work.

Tracing – How to build a specific binary tree from a particular set of information?

I run an algorithm to solve a problem that returns a set of information related to a binary tree associated with these problems. To illustrate the results obtained, I try to draw the binary tree. I make the right plot in the picture below. But I like to draw the tree on the left.

The question is: how to draw the right binary tree in the figure below?

enter the description of the image here

The input data for this are two lists. The first contains the "path" of the solution (for the tree in the left / right below: paths = {{0, 0, 0, 0, 0}, {0, 1, 1, 1}}) the second list contains the number of nodes in each level (for the right tree below: nodes_leves = {1, 2, 4, 4}).

I have tried searching for functions associated with charts, trees, etc., but I have not found a solution to draw this specific tree.

Thanks in advance

Comparison of AI search algorithms in the Java game tree

I have a program that compares three game tree search algorithms:

  1. Minimax,
  2. Alpha-beta size,
  3. Alpha-beta size with moving order.

So here is my code:

net.coderodde.zerosum.ai.impl.MinimaxGameEngine

package net.coderodde.zerosum.ai.impl;

import net.coderodde.zerosum.ai.EvaluatorFunction;
import net.coderodde.zerosum.ai.AbstractGameEngine;
import net.coderodde.zerosum.ai.AbstractState;

/**
 * This class implements the 
 * Minimax algorithm for 
 * zero-sum two-player games.
 * 
 * @param  the game state type.
 * @param 

the player color type. * @author Rodion "rodde" Efremov * @version 1.6 (May 26, 2019) */ public final class MinimaxGameEngine, P extends Enum

> extends AbstractGameEngine { /** * Constructs this minimax game engine. * @param evaluatorFunction the evaluator function. * @param depth the search depth. */ public MinimaxGameEngine(EvaluatorFunction evaluatorFunction, int depth) { super(evaluatorFunction, depth, Integer.MAX_VALUE); } /** * {@inheritDoc } */ @Override public S makePly(S state, P minimizingPlayer, P maximizingPlayer, P initialPlayer) { state.setDepth(depth); // Do the game tree search: return makePlyImplTopmost(state, minimizingPlayer, maximizingPlayer, initialPlayer); } private S makePlyImplTopmost(S state, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { S bestState = null; if (currentPlayer == maximizingPlayer) { double tentativeValue = Double.NEGATIVE_INFINITY; for (S childState : state.children()) { double value = makePlyImpl(childState, depth - 1, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; bestState = childState; } } } else { // Here, 'initialPlayer == minimizingPlayer'. double tentativeValue = Double.POSITIVE_INFINITY; for (S childState : state.children()) { double value = makePlyImpl(childState, depth - 1, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; bestState = childState; } } } return bestState; } /** * Performs a single step down the game tree branch. * * @param state the starting state. * @param depth the maximum depth of the game tree. * @param minimizingPlayer the minimizing player. * @param maximizingPlayer the maximizing player. * @param currentPlayer the current player. * * @return the value of the best ply. */ private double makePlyImpl(S state, int depth, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { if (state.getDepth() == 0 || state.checkVictory() != null || state.isTerminal()) { return evaluatorFunction.evaluate(state); } if (currentPlayer == maximizingPlayer) { double tentativeValue = Double.NEGATIVE_INFINITY; for (S child : state.children()) { double value = makePlyImpl(child, depth - 1, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; } } return tentativeValue; } else { // Here, 'initialPlayer == minimizingPlayer'. double tentativeValue = Double.POSITIVE_INFINITY; for (S child : state.children()) { double value = makePlyImpl(child, depth - 1, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; } } return tentativeValue; } } }

net.coderodde.zerosum.ai.impl.AlphaBetaPruningGameEngine

package net.coderodde.zerosum.ai.impl;

import net.coderodde.zerosum.ai.EvaluatorFunction;
import net.coderodde.zerosum.ai.AbstractGameEngine;
import net.coderodde.zerosum.ai.AbstractState;

/**
 * This class implements the 
 * 
 * Alpha-beta pruning algorithm for zero-sum two-player games.
 * 
 * @param  the game state type.
 * @param 

the player color type. * @author Rodion "rodde" Efremov * @version 1.6 (May 26, 2019) * @version 1.61 (Sep 12, 2019) * @since 1.6 (May 26, 2019) */ public final class AlphaBetaPruningGameEngine, P extends Enum

> extends AbstractGameEngine { /** * Constructs this minimax game engine. * @param evaluatorFunction the evaluator function. * @param depth the search depth. */ public AlphaBetaPruningGameEngine(EvaluatorFunction evaluatorFunction, int depth) { super(evaluatorFunction, depth, Integer.MAX_VALUE); } /** * {@inheritDoc} */ public S makePly(S state, P minimizingPlayer, P maximizingPlayer, P initialPlayer) { state.setDepth(depth); // Do the game tree search with Alpha-beta pruning: return makePlyImplTopmost(state, depth, -Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, minimizingPlayer, maximizingPlayer, initialPlayer); } /** * Pefrorms the topmost search of a game tree. * * @param state the state to start the search from. * @param depth the depth of the tree to search. * @param alpha the alpha cut-off value. * @param beta the beta cut-off value. * @param minimizingPlayer the minimizing player color. * @param maximizingPlayer the maximizing player color. * @param currentPlayer the current player color. * @return */ private S makePlyImplTopmost(S state, int depth, double alpha, double beta, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { S bestState = null; if (currentPlayer == maximizingPlayer) { double tentativeValue = Double.NEGATIVE_INFINITY; for (S childState : state.children()) { double value = makePlyImpl(childState, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; bestState = childState; } alpha = Math.max(alpha, tentativeValue); if (alpha >= beta) { return bestState; } } } else { // Here, 'initialPlayer == minimizingPlayer'. double tentativeValue = Double.POSITIVE_INFINITY; for (S childState : state.children()) { double value = makePlyImpl(childState, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; bestState = childState; } beta = Math.min(beta, tentativeValue); if (alpha >= beta) { return bestState; } } } return bestState; } /** * Performs a single step down the game tree. * * @param state the starting state. * @param depth the maximum depth of the game tree. * @param alpha the alpha cut-off. * @param beta the beta cut-off. * @param minimizingPlayer the minimizing player. * @param maximizingPlayer the maximizing player. * @param currentPlayer the current player. * * @return the value of the best ply. */ private double makePlyImpl(S state, int depth, double alpha, double beta, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { if (state.getDepth() == 0 || state.checkVictory() != null || state.isTerminal()) { return evaluatorFunction.evaluate(state); } if (currentPlayer == maximizingPlayer) { double tentativeValue = Double.NEGATIVE_INFINITY; for (S child : state.children()) { double value = makePlyImpl(child, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; } alpha = Math.max(alpha, tentativeValue); if (alpha >= beta) { break; } } return tentativeValue; } else { // Here, 'initialPlayer == minimizingPlayer'. double tentativeValue = Double.POSITIVE_INFINITY; for (S child : state.children()) { double value = makePlyImpl(child, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; } beta = Math.min(beta, tentativeValue); if (alpha >= beta) { break; } } return tentativeValue; } } }

net.coderodde.zerosum.ai.impl.SortingAlphaBetaPruningGameEngine

package net.coderodde.zerosum.ai.impl;

import java.util.List;
import net.coderodde.zerosum.ai.EvaluatorFunction;
import net.coderodde.zerosum.ai.AbstractGameEngine;
import net.coderodde.zerosum.ai.AbstractState;
import net.coderodde.zerosum.ai.demo.DemoPlayerColor;

/**
 * This class implements the 
 * 
 * Alpha-beta pruning algorithm for zero-sum two-player games.
 * 
 * @param  the game state type.
 * @param 

the player color type. * @author Rodion "rodde" Efremov * @version 1.6 (May 26, 2019) * @version 1.61 (Sep 12, 2019) * @since 1.6 (May 26, 2019) */ public final class SortingAlphaBetaPruningGameEngine , P extends Enum

> extends AbstractGameEngine { /** * Constructs this minimax game engine. * @param evaluatorFunction the evaluator function. * @param depth the search depth. */ public SortingAlphaBetaPruningGameEngine(EvaluatorFunction evaluatorFunction, int depth) { super(evaluatorFunction, depth, Integer.MAX_VALUE); } /** * {@inheritDoc} */ public S makePly(S state, P minimizingPlayer, P maximizingPlayer, P initialPlayer) { state.setDepth(depth); // Do the game tree search with Alpha-beta pruning: return makePlyImplTopmost(state, depth, -Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, minimizingPlayer, maximizingPlayer, initialPlayer); } /** * Pefrorms the topmost search of a game tree. * * @param state the state to start the search from. * @param depth the depth of the tree to search. * @param alpha the alpha cut-off value. * @param beta the beta cut-off value. * @param minimizingPlayer the minimizing player color. * @param maximizingPlayer the maximizing player color. * @param currentPlayer the current player color. * @return */ private S makePlyImplTopmost(S state, int depth, double alpha, double beta, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { S bestState = null; List children = state.children(); if (currentPlayer == maximizingPlayer) { children.sort((a, b) -> { double valueOfA = super.evaluatorFunction.evaluate(a); double valueOfB = super.evaluatorFunction.evaluate(b); return Double.compare(valueOfA, valueOfB); }); double tentativeValue = Double.NEGATIVE_INFINITY; for (S childState : children) { double value = makePlyImpl(childState, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; bestState = childState; } alpha = Math.max(alpha, tentativeValue); if (alpha >= beta) { return bestState; } } } else { // Here, 'initialPlayer == minimizingPlayer'. children.sort((a, b) -> { double valueOfA = super.evaluatorFunction.evaluate(a); double valueOfB = super.evaluatorFunction.evaluate(b); return Double.compare(valueOfB, valueOfA); }); double tentativeValue = Double.POSITIVE_INFINITY; for (S childState : children) { double value = makePlyImpl(childState, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; bestState = childState; } beta = Math.min(beta, tentativeValue); if (alpha >= beta) { return bestState; } } } return bestState; } /** * Performs a single step down the game tree. * * @param state the starting state. * @param depth the maximum depth of the game tree. * @param alpha the alpha cut-off. * @param beta the beta cut-off. * @param minimizingPlayer the minimizing player. * @param maximizingPlayer the maximizing player. * @param currentPlayer the current player. * * @return the value of the best ply. */ private double makePlyImpl(S state, int depth, double alpha, double beta, P minimizingPlayer, P maximizingPlayer, P currentPlayer) { if (state.getDepth() == 0 || state.checkVictory() != null || state.isTerminal()) { return evaluatorFunction.evaluate(state); } List children = state.children(); if (currentPlayer == maximizingPlayer) { children.sort((a, b) -> { double valueOfA = super.evaluatorFunction.evaluate(a); double valueOfB = super.evaluatorFunction.evaluate(b); return Double.compare(valueOfA, valueOfB); }); double tentativeValue = Double.NEGATIVE_INFINITY; for (S child : children) { double value = makePlyImpl(child, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue < value) { tentativeValue = value; } alpha = Math.max(alpha, tentativeValue); if (alpha >= beta) { break; } } return tentativeValue; } else { // Here, 'initialPlayer == minimizingPlayer'. children.sort((a, b) -> { double valueOfA = super.evaluatorFunction.evaluate(a); double valueOfB = super.evaluatorFunction.evaluate(b); return Double.compare(valueOfB, valueOfA); }); double tentativeValue = Double.POSITIVE_INFINITY; for (S child : children) { double value = makePlyImpl(child, depth - 1, alpha, beta, minimizingPlayer, maximizingPlayer, minimizingPlayer); if (tentativeValue > value) { tentativeValue = value; } beta = Math.min(beta, tentativeValue); if (alpha >= beta) { break; } } return tentativeValue; } } }

net.coderodde.zerosum.ai.impl.AbstractGameEngine

package net.coderodde.zerosum.ai;

/**
 * This abstract class defines the API for game-playing AI algorithms such as 
 * Minimax, Alpha-beta pruning, and so on.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (May 26, 2019)
 * @param  the board state type.
 * @param 

the player color type. */ public abstract class AbstractGameEngine< S extends AbstractState, P extends Enum

> { /** * The minimum depth of the game tree to traverse. */ private static final int MINIMUM_DEPTH = 1; /** * The depth, after reaching which, the search spawns isolated tasks for a * thread pool to process. */ private static final int MINIMUM_PARALLEL_DEPTH = 1; /** * The state evaluator function. */ protected EvaluatorFunction evaluatorFunction; /** * The maximum depth of the game tree to construct. */ protected int depth; /** * The depth after which to switch to parallel computation. */ protected int parallelDepth; /** * Constructs this game engine with given parameters. Note that if * {@code parallelDepth > depth}, the entire computation will be run in this * thread without spawning * @param evaluatorFunction * @param depth * @param parallelDepth */ public AbstractGameEngine(EvaluatorFunction evaluatorFunction, int depth, int parallelDepth) { setEvaluatorFunction(evaluatorFunction); setDepth(depth); setParallelDepth(parallelDepth); } public EvaluatorFunction getEvaluatorFunction() { return evaluatorFunction; } public int getDepth() { return depth; } public int getParallelDepth() { return parallelDepth; } public void setEvaluatorFunction(EvaluatorFunction evaluatorFunction) { this.evaluatorFunction = evaluatorFunction; } public void setDepth(int depth) { this.depth = checkDepth(depth); } public void setParallelDepth(int parallelDepth) { this.parallelDepth = checkParallelDepth(parallelDepth); } /** * Computes and makes a single move. * @param state the source game state. * @param minimizingPlayer the player that seeks to minimize the score. * @param maximizingPlayer the player that seeks to maximize the score. * @param initialPlayer the initial player. Must be either * {@code minimizingPlayer} or {@code maximizingPlayer}. The ply is computed * for this specific player. * @return the next game state. */ public abstract S makePly(S state, P minimizingPlayer, P maximizingPlayer, P initialPlayer); /** * Validates the depth candidate. * @param depthCandidate the depth candidate to validate. * @return the depth candidate if valid. */ private int checkDepth(int depthCandidate) { if (depthCandidate < MINIMUM_DEPTH) { throw new IllegalArgumentException( "The requested depth (" + depthCandidate + ") is too " + "small. Must be at least " + MINIMUM_DEPTH + "."); } return depthCandidate; } /** * Validates the parallel depth candidate. * @param parallelDepthCandidate the parallel depth candidate to validate. * @return the parallel depth candidate. */ private int checkParallelDepth(int parallelDepthCandidate) { if (parallelDepthCandidate < MINIMUM_PARALLEL_DEPTH) { throw new IllegalArgumentException( "The requested parallel depth (" + parallelDepthCandidate + ") is too small. Must be at least " + MINIMUM_PARALLEL_DEPTH + "."); } return parallelDepthCandidate; } }

net.coderodde.zerosum.ai.impl.AbstractState

package net.coderodde.zerosum.ai;

import java.util.List;

/**
 * This interface defines the API for search states.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (May 26, 2019)
 * @param  the actual state type.
 */
public abstract class AbstractState,
                                    P extends Enum

> { /** * The depth of this state. */ private int depth; /** * Returns the next ply. * * @return the collection of next states. */ public abstract List children(); /** * Returns {@code true} if this state is a terminal state. * * @return a boolean indicating whether this state is terminal. */ public abstract boolean isTerminal(); /** * Checks whether this state represents a victory of a player. * * @return the winning player or {@code null} if there is no such. */ public abstract P checkVictory(); public int getDepth() { return depth; } public void setDepth(int depth) { this.depth = depth; } }

net.coderodde.zerosum.ai.impl.EvaluatorFunction

package net.coderodde.zerosum.ai;

/**
 * This interface defines the API for evaluation functions.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (May 26, 2019)
 * @param  the state type.
 */
public interface EvaluatorFunction {

    /**
     * Evaluates the given state and returns the result.
     * @param state the state to evaluate.
     * @return the evaluation score.
     */
    public double evaluate(S state);
}

Request for criticism

I would like to hear comments on the general design of the code, the efficiency and readability / maintainability of my code. Yet tell me everything that goes through your head.