Hello, Buffer

Weighted distrobution with non-uniform sets

The problem is as follows A customer will order a set of views in one of two configurations:

Full Frame logo: 1/4 Logo:

    +------------+       +-----+------+
    |            |       | A   | B    |
    |            |       +-----+------+
    |Full Frame  |       | C   | D    |
    +------------+       +-----+------+

So i have a set of customers with properties:

  • Name
  • Limit (Amout of views they purchased)
  • Shown (Amout of views aquired)
  • FullScreen (If it’s a fullscreen or not)

I then try to generate every possible screen and give it a score(Later to be used as weight): I also iterate over every customer to gain a `total_remaining` for use in the `weight`

for customer in customers:
    remaining = customer['limit'] - customer['shown']
    total_remaining += remaining
    if remaining < 0:
        continue
    if customer['fullscreen']:
        possible_fullscreeens.append({
            'name': customer['name'],
            'limit': customer['limit'],
            'shown': customer['shown'],
            'remaining': remaining
        })
    if not customer['fullscreen']:
        possible_quarts.append({
            'name': customer['name'],
            'limit': customer['limit'],
            'shown': customer['shown'],
            'remaining': remaining
        })

Both fullscreen and quarts are now in a temporary dict, i neeede to iterate over twice to get the `total_remaining`

And for then we add all possible screens in `possible_ads` For the fullscreen this is straight forward:

for full in possible_fullscreeens:
    possible_ads.append({
        "name":
        full['name'],
        "score":
        full['remaining'],
        "remaining":
        full['remaining'],
        "weight": (full['remaining'] / total_remaining) * 100.0
    })

For quarts this is a lot more work, and i probably did it wrong in a stupid way. But here we go.

# First i get all the possible combinations for the given set
possible_combinations = get_possible_combinations(len(possible_quarts), 4)
for subset in itertools.combinations(possible_quarts, 4):
    score = 0
    name = ""
    for customer in subset:
        customer_name = customer['name']
        name += customer_name + ','
        score += customer['remaining'] / 4.0

    possible_ads.append({
        "name":
        name,
        "score":
        score,
        "remaining":
        score,
        "weight":
        ((score / total_remaining) * 100.0) / (possible_combinations)
    })

Then we use the weights to do a weighted random selection

(total_remaining, possible_ads) = update_adds()
if (len(possible_ads) <= 1):
    print("All done")
    break
weights = []
for ad in possible_ads:
    weights.append(ad['weight'])

ad = secure_random.choices(possible_ads, weights=weights, k=1)[0]

My assumtion is that it should take about as long for everyone to reach the limit, i have some wierd distrobution in that respect This is the response after 100_000 runs, the lower letters have high numbers because their limits is low, and `A`,`A1` and `A2` are fullscreen

A    %:      24.82
A2   %:      24.908
A3   %:      24.81
B    %:      19.68
C    %:      19.296
D    %:      19.42
F    %:      3.7216
G    %:      36.724000000000004
H    %:      36.832
I    %:      37.532
K    %:      37.104
L    %:      100.02
M    %:      100.05
P    %:      105.0
Q    %:      110.00000000000001

This needs more work

Hello, WordPress

I’m currently in the process of setting up a more streamlined bloggin pipeline from my trusty emacs config. Hopefully this will enable me to share snippets and thoughts for my own sick pleasure.

Currently i’m working in spacemacs and org mode, i will check if some features are working

for x in range(0,10):
    print(x)

OMG yes it can print code with syntax, this is the best shit 🙂

#[system(for_each)]
fn pathfinding_human(
    _human: &Human,
    transform: &mut Transform,
    pathfinding: &mut PathfindingAgent,
    #[resource] _view_rect: &CamViewRect,
) {
    if pathfinding.path.is_empty() {
        let result = astar(
            &crate::util::Vec2::to_ivec2(transform.position),
            |&pos| linear_successors_ivec2(pos),
            |&pos| pos.distance_to(pathfinding.target),
            |&pos| pos == pathfinding.target,
        )
        .unwrap();
        println!("PATH IS: {:?}", result);
        pathfinding.path = result.0;
    }

    let cur_position = transform.position;

    let dir: crate::util::Vec2 = IVec2::to_vec2(pathfinding.path[0]) - cur_position;
    println!("Direction :{:?} \n Mag:{:?}\n Norm:{:?}", dir, dir.mag(), dir.norm());
    if dir.mag() > pathfinding.speed {
        // if transform.position.to_ivec2().distance_to(*pathfinding.path.first().unwrap()) == 0 {
        transform.position += dir.norm() * pathfinding.speed;
    } else {
        println!("Popping point on path: {:?}", pathfinding.path);
        transform.position = pathfinding.path[0].into();
        pathfinding.path.remove(0);
    }
}

Hell yea, thats some saxy saxy shit