How Vilvik works
A picture of the moving parts so you know what the platform is doing on your behalf.
This page is a map. It shows the major pieces Vilvik uses to run your jobs and how they talk to each other. You do not need to know any of this to use the platform, but the picture helps when you read about features later on.
The platform at a glance¶
secure environment"] end subgraph Store ["Your data"] DB[("Submissions, results, credits")] end subgraph External ["External services"] Pay["Payment provider"] Mail["Email service"] end Start --> Browser Browser -- "submit or browse" --> Web Web -- "enqueue and bill" --> Queue Queue -- "dispatch" --> Worker Worker -- "save result" --> DB Web <-- "read or share" --> DB Web -- "subscribe or top up" --> Pay Pay -- "confirm" --> Web Worker -- "completed" --> Mail Mail -- "notify" --> Inbox Worker -- "webhook delivery" --> Hook
A short tour of the boxes:
- Web and REST API. What you talk to from the website or from your own code. It validates your input, checks that your tier or credit balance allows the run, and hands the job to the queue. See Creating a submission for the website path and API overview for the API path.
- Job queue. Holds jobs until a worker is free. This is why a submission can sit briefly in
queuedbefore it starts. - Worker. A fresh, isolated environment per job. Your fitness function (and any uploaded code) runs here. The worker writes the best solution, charts, and logs back to the database.
- Submissions, results, credits. The store the website and the API read from when you open a result page or list your submissions. Sharing a result, forking a run, and counting your credits all read from the same place.
- Payment provider. Subscriptions and credit top-ups are charged through a payment provider. We never see your card number. See Plans and tiers.
- Email service. Sends the notification when a long-running job finishes, and the transactional emails for sign-up and password resets.
Try one without leaving this page¶
The example below runs a small genetic algorithm right in the docs. Click Run example and the same code that you see runs on our servers; the result panel appears below the code.
Evolve a string toward a target
A classic intro example. The GA mutates a population of byte sequences until one of them spells "Hello, GA!".
import pygad
# Evolve a population of byte sequences toward the target "Hello, GA!".
# Each "gene" is an ASCII code; fitness counts how many positions match.
TARGET = "Hello, GA!"
TARGET_CODES = [ord(c) for c in TARGET]
def fitness_func(ga, solution, solution_idx):
return sum(1 for a, b in zip(solution, TARGET_CODES) if int(a) == b)
ga = pygad.GA(
num_generations=80,
sol_per_pop=40,
num_parents_mating=10,
fitness_func=fitness_func,
num_genes=len(TARGET),
gene_type=int,
gene_space=range(32, 127), # printable ASCII
mutation_probability=0.05,
parent_selection_type="sss",
crossover_type="single_point",
mutation_type="random",
stop_criteria=f"reach_{len(TARGET)}",
)
ga.run()
solution, fitness, _ = ga.best_solution(ga.last_generation_fitness)
print("best:", "".join(chr(int(x)) for x in solution), "fitness:", fitness)
The example above evolves a population of random characters toward the target string. Most runs converge in well under a second. Try the subset-sum example too, which picks numbers from a list to hit a target sum:
Subset sum
Pick a subset of the given numbers whose sum equals the target. Bit-string genome, sum-distance fitness.
import pygad
# Pick a subset of these numbers that sums to TARGET.
NUMBERS = [12, 7, 19, 3, 15, 8, 22, 11, 5, 17]
TARGET = 50
def fitness_func(ga, solution, solution_idx):
chosen_sum = sum(n for n, take in zip(NUMBERS, solution) if int(take) == 1)
return -abs(chosen_sum - TARGET) # 0 means exact match
ga = pygad.GA(
num_generations=60,
sol_per_pop=30,
num_parents_mating=8,
fitness_func=fitness_func,
num_genes=len(NUMBERS),
gene_type=int,
gene_space=[0, 1],
mutation_probability=0.08,
stop_criteria="reach_0",
)
ga.run()
solution, fitness, _ = ga.best_solution(ga.last_generation_fitness)
picked = [n for n, take in zip(NUMBERS, solution) if int(take) == 1]
print("picked:", picked, "sum:", sum(picked), "fitness:", fitness)
Both examples use the same evolution loop your own submissions use, just with smaller numbers so the result comes back quickly.
Where to look next¶
The pages below zoom into one part of the picture:
- Creating a submission walks through a submission from form to result.
- Plans and tiers shows how your effective tier is decided.
- API overview shows what an API call looks like from the outside.
- Sharing a submission or result publicly covers the visibility options on results.