Skip to content

Commit ca97cda

Browse files
Merge pull request #87 from priyansh-narang2308/feat/theory-knowledge-info-tooltips
[WOC] Add educational theory tooltips across all algorithm configuration forms
2 parents 5988a81 + 7ae867a commit ca97cda

18 files changed

+250
-29
lines changed

app/_components/TheoryTooltip.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import { Info } from "lucide-react";
5+
import { theoryData } from "@/app/_data/theory";
6+
7+
export default function TheoryTooltip({ id }) {
8+
const [isVisible, setIsVisible] = useState(false);
9+
const data = theoryData[id];
10+
11+
if (!data) return null;
12+
13+
return (
14+
<div className="relative inline-block ml-2 group">
15+
<button
16+
type="button"
17+
onMouseEnter={() => setIsVisible(true)}
18+
onMouseLeave={() => setIsVisible(false)}
19+
onClick={() => setIsVisible(!isVisible)}
20+
className="text-gray-600 hover:text-blue-600 transition-colors duration-200 focus:outline-none flex items-center"
21+
aria-label="Theoretical Information"
22+
>
23+
<Info size={18} />
24+
</button>
25+
26+
{isVisible && (
27+
<div className="absolute z-50 bottom-full left-1/2 -translate-x-1/2 mb-3 w-72 p-4 rounded-2xl bg-white/90 backdrop-blur-xl border border-white/20 shadow-[0_8px_32px_0_rgba(31,38,135,0.15)] transition-all duration-200 ease-out transform opacity-100 scale-100">
28+
<div className="relative">
29+
<h5 className="font-bold text-gray-900 text-sm mb-1 uppercase tracking-wider">
30+
{data.title}
31+
</h5>
32+
<p className="text-gray-600 text-xs leading-relaxed">
33+
{data.explanation}
34+
</p>
35+
<div className="absolute -bottom-6 left-1/2 -translate-x-1/2 border-8 border-transparent border-t-white/90" />
36+
</div>
37+
</div>
38+
)}
39+
</div>
40+
);
41+
}

app/_data/theory.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
export const theoryData = {
2+
populationSize: {
3+
title: "Population Size",
4+
explanation: "The number of individuals in each generation. A larger population increases genetic diversity and the chance of finding a global optimum but requires more computational power.",
5+
},
6+
generations: {
7+
title: "Generations",
8+
explanation: "The total number of iterations the evolutionary process will run. More generations allow the population to converge on better solutions but increase execution time.",
9+
},
10+
cxpb: {
11+
title: "Crossover Probability",
12+
explanation: "The probability that two parent individuals will exchange genetic material. High values promote the recombination of good traits from different individuals.",
13+
},
14+
mutpb: {
15+
title: "Mutation Probability",
16+
explanation: "The probability that an individual's genes will be randomly altered. This introduces new genetic material, helping the population escape local optima.",
17+
},
18+
hof: {
19+
title: "Hall of Fame",
20+
explanation: "A special archive that stores the absolute best individuals found throughout the entire run, ensuring that the top solutions are never lost during evolution.",
21+
},
22+
mu: {
23+
title: "Mu (μ)",
24+
explanation: "The number of individuals to be selected as parents for the next generation. It defines the size of the breeding pool.",
25+
},
26+
lambda: {
27+
title: "Lambda (λ)",
28+
explanation: "The number of children to be generated in each step. This determines the exploratory capacity of the algorithm per generation.",
29+
},
30+
tournamentSize: {
31+
title: "Tournament Size",
32+
explanation: "Used in selection: 'k' individuals are picked at random, and the best one wins. A larger tournament size increases selection pressure.",
33+
},
34+
phi1: {
35+
title: "Cognitive Coefficient (φ1)",
36+
explanation: "In PSO, this scales the influence of a particle's personal best performance on its current velocity.",
37+
},
38+
phi2: {
39+
title: "Social Coefficient (φ2)",
40+
explanation: "In PSO, this scales the influence of the swarm's global best performance on a particle's current velocity.",
41+
},
42+
dimensions: {
43+
title: "Dimensions",
44+
explanation: "The number of variables or parameters that the algorithm is trying to optimize simultaneously.",
45+
},
46+
algorithmStrategy: {
47+
title: "Algorithm Strategy",
48+
explanation: "The high-level logic governing evolution. 'eaSimple' is a basic generational model, while 'eaMuPlusLambda' and 'eaMuCommaLambda' use more advanced selection and replacement mechanics common in Evolution Strategies.",
49+
},
50+
psoStrategy: {
51+
title: "PSO Strategy",
52+
explanation: "Defines the velocity and position update logic for particles. 'original' uses the standard PSO formulas, while variants like 'multiswarm' or 'speciation' help the algorithm handle more complex optimization landscapes.",
53+
},
54+
benchmarkFunction: {
55+
title: "Benchmark Function",
56+
explanation: "Mathematical functions used to evaluate optimization performance. Each function (like Ackley, Rastrigin, or Rosenbrock) represents a unique 'landscape' with different challenges for the algorithm to solve.",
57+
},
58+
weights: {
59+
title: "Weights",
60+
explanation: "Coefficients that determine the importance of different objectives in the fitness function. If you have multiple goals, weights help the algorithm prioritize between them (e.g., maximizing accuracy vs. minimizing complexity).",
61+
},
62+
matingFunction: {
63+
title: "Mating (Crossover)",
64+
explanation: "The mechanism of biological recombination. It combines genetic information from two parents to generate offspring, aiming to produce better solutions by merging high-performing traits.",
65+
},
66+
mutationFunction: {
67+
title: "Mutation",
68+
explanation: "Introduces random changes to individuals. This prevents premature convergence and ensures the algorithm explores new areas of the search space, maintaining genetic diversity.",
69+
},
70+
selectionFunction: {
71+
title: "Selection",
72+
explanation: "The 'survival of the fittest' phase. It determines which individuals from the current population will be kept as parents for the next generation based on their fitness scores.",
73+
},
74+
datasetUrl: {
75+
title: "Dataset Source",
76+
explanation: "The raw data used for training and evaluation. In ML tuning, the algorithm uses this data to test how well different model parameters perform.",
77+
},
78+
targetColumn: {
79+
title: "Target Variable",
80+
explanation: "The specific column in your dataset that you want the model to predict (the dependent variable).",
81+
},
82+
mlEvalFunction: {
83+
title: "ML Evaluation",
84+
explanation: "The metric used to judge the performance of the machine learning model (e.g., Accuracy, F1-score, or MSE). The EA optimizes this value.",
85+
},
86+
individualSize: {
87+
title: "Individual Size",
88+
explanation: "The length of the chromosome or the number of genes representing a solution. For example, in bit manipulation, it's the number of bits per individual.",
89+
},
90+
minMaxBoundaries: {
91+
title: "Search Boundaries",
92+
explanation: "The constraints on the search space. Defines the minimum and maximum values that a gene (or particle position) can take.",
93+
},
94+
gpPrimitiveSet: {
95+
title: "Primitive Set",
96+
explanation: "The building blocks for Genetic Programs. It includes functions (operators like +, -, *, /) and terminals (constants like 1, 2, or variables like 'x'). Crossing these creates complex tree structures.",
97+
},
98+
treeGenerator: {
99+
title: "Tree Generator",
100+
explanation: "The algorithm used to create the initial programs. 'genFull' creates balanced trees where every branch reaches max depth, while 'genHalfAndHalf' provides a mix of short and deep trees for better diversity.",
101+
},
102+
bloatLimits: {
103+
title: "Bloat Control",
104+
explanation: "Prevents programs from growing excessively large without improving fitness. By setting a height limit, we ensure the solutions remain computationally efficient and readable.",
105+
}
106+
};

app/create/_components/chooseAlgorithm.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import TheoryTooltip from "../../_components/TheoryTooltip";
12
import { algorithmData } from "@/app/_data/algorithms";
23

34
export const ChooseAlgo = ({
@@ -12,10 +13,14 @@ export const ChooseAlgo = ({
1213
setMu,
1314
lambda,
1415
setLambda,
16+
theoryId = "algorithmStrategy",
1517
}) => {
1618
return (
1719
<div className="my-4">
18-
<h4 className="text-lg font-bold mb-4">{title}</h4>
20+
<h4 className="flex items-center text-lg font-bold mb-4">
21+
{title}
22+
<TheoryTooltip id={theoryId} />
23+
</h4>
1924
<div className="grid grid-cols-2 gap-4 align-top">
2025
{algoData.map((algorithm, index) => (
2126
<button
@@ -77,7 +82,10 @@ export const ChooseAlgo = ({
7782
)}
7883
<div className="grid grid-cols-2 gap-4 mt-4">
7984
<div>
80-
<h6 className="text-lg font-bold mb-4">Mu</h6>
85+
<h6 className="flex items-center text-lg font-bold mb-4">
86+
Mu
87+
<TheoryTooltip id="mu" />
88+
</h6>
8189
<input
8290
type="number"
8391
value={mu.toString()}
@@ -108,7 +116,10 @@ export const ChooseAlgo = ({
108116
/>
109117
</div>
110118
<div>
111-
<h6 className="text-lg font-bold mb-4">Lambda</h6>
119+
<h6 className="flex items-center text-lg font-bold mb-4">
120+
Lambda
121+
<TheoryTooltip id="lambda" />
122+
</h6>
112123
<input
113124
type="number"
114125
value={lambda.toString()}

app/create/_components/chooseMatingFunction.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
2+
13
export default function ChooseMatingFunction({
24
title = "Step 6: Choose a mating function.",
35
mateData,
@@ -12,7 +14,10 @@ export default function ChooseMatingFunction({
1214
}) {
1315
return (
1416
<div className="mt-8">
15-
<h4 className="text-lg font-bold mb-4">{title}</h4>
17+
<h4 className="flex items-center text-lg font-bold mb-4">
18+
{title}
19+
<TheoryTooltip id="matingFunction" />
20+
</h4>
1621
{/* grid: each element has a name and description */}
1722
<div className="grid grid-cols-2 gap-4 align-top">
1823
{mateData.map((mate, index) => (

app/create/_components/chooseMutateFunction.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
2+
13
export default function ChooseMutationFunction({
24
title = "Step 7: Choose a mutation function.",
35
mutationData,
@@ -11,7 +13,10 @@ export default function ChooseMutationFunction({
1113
}) {
1214
return (
1315
<div className="mt-16">
14-
<h4 className="text-lg font-bold mb-4">{title}</h4>
16+
<h4 className="flex items-center text-lg font-bold mb-4">
17+
{title}
18+
<TheoryTooltip id="mutationFunction" />
19+
</h4>
1520
{/* grid: each element has a name and description */}
1621
<div className="grid grid-cols-2 gap-4 align-top">
1722
{mutationData.map((mut, index) => (

app/create/_components/chooseSelectionFunction.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { selectionData } from "@/app/_data/selection";
2+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
23

34
export default function ChooseSelectionFunction({
45
title = "Step 8: Choose a selection function.",
@@ -13,7 +14,10 @@ export default function ChooseSelectionFunction({
1314
}) {
1415
return (
1516
<div className="mt-16">
16-
<h4 className="text-lg font-bold mb-4">{title}</h4>
17+
<h4 className="flex items-center text-lg font-bold mb-4">
18+
{title}
19+
<TheoryTooltip id="selectionFunction" />
20+
</h4>
1721
<div className="grid grid-cols-2 gap-4 align-top">
1822
{selData.map((sel, index) => (
1923
<button
@@ -45,7 +49,10 @@ export default function ChooseSelectionFunction({
4549

4650
{selectFunc === "selTournament" && (
4751
<div className="mt-4">
48-
<h5 className="text-lg font-bold mb-4">Tournament Size</h5>
52+
<h5 className="flex items-center text-lg font-bold mb-4">
53+
Tournament Size
54+
<TheoryTooltip id="tournamentSize" />
55+
</h5>
4956
<input
5057
type="number"
5158
value={tempTourSize}

app/create/_components/chooseWeights.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
"use client";
21
import { useState } from "react";
2+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
33

44
export default function ChooseWeights({
55
title = "Step 2: Parameters to optimize (weights)",
@@ -14,7 +14,10 @@ export default function ChooseWeights({
1414

1515
return (
1616
<div className="mt-8">
17-
<h4 className="text-lg font-bold mb-4">{title}</h4>
17+
<h4 className="flex items-center text-lg font-bold mb-4">
18+
{title}
19+
<TheoryTooltip id="weights" />
20+
</h4>
1821

1922
{/*
2023
@@ -104,8 +107,9 @@ export default function ChooseWeights({
104107
)}
105108
</div>
106109
<div className="flex flex-col">
107-
<h5 className="text-lg font-bold">
110+
<h5 className="flex items-center text-lg font-bold">
108111
Optimization Parameters
112+
<TheoryTooltip id="weights" />
109113
</h5>
110114

111115
<table className="w-full text-center">

app/create/_components/configureAlgoParams.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import TheoryTooltip from "../../_components/TheoryTooltip";
2+
13
export default function ConfigureAlgoParams({
24
title = `Step 10: Configure Genetic Algorithm`,
35
populationSize,
@@ -23,7 +25,10 @@ export default function ConfigureAlgoParams({
2325

2426
<div className="grid grid-cols-2 gap-4">
2527
<div>
26-
<h5 className="text-lg font-bold mb-4">Population Size</h5>
28+
<h5 className="flex items-center text-lg font-bold mb-4">
29+
Population Size
30+
<TheoryTooltip id="populationSize" />
31+
</h5>
2732
<input
2833
type="number"
2934
value={populationSize}
@@ -44,7 +49,10 @@ export default function ConfigureAlgoParams({
4449
/>
4550
</div>
4651
<div>
47-
<h5 className="text-lg font-bold mb-4">Generations</h5>
52+
<h5 className="flex items-center text-lg font-bold mb-4">
53+
Generations
54+
<TheoryTooltip id="generations" />
55+
</h5>
4856
<input
4957
type="number"
5058
value={generations}
@@ -66,8 +74,9 @@ export default function ConfigureAlgoParams({
6674
/>
6775
</div>
6876
<div>
69-
<h5 className="text-lg font-bold mb-4">
77+
<h5 className="flex items-center text-lg font-bold mb-4">
7078
Crossover Probability
79+
<TheoryTooltip id="cxpb" />
7180
</h5>
7281
<input
7382
type="number"
@@ -99,8 +108,9 @@ export default function ConfigureAlgoParams({
99108
/>
100109
</div>
101110
<div>
102-
<h5 className="text-lg font-bold mb-4">
111+
<h5 className="flex items-center text-lg font-bold mb-4">
103112
Mutation Probability
113+
<TheoryTooltip id="mutpb" />
104114
</h5>
105115
<input
106116
type="number"
@@ -132,8 +142,9 @@ export default function ConfigureAlgoParams({
132142
/>
133143
</div>
134144
<div>
135-
<h5 className="text-lg font-bold mb-4">
145+
<h5 className="flex items-center text-lg font-bold mb-4">
136146
Hall of Fame Size
147+
<TheoryTooltip id="hof" />
137148
</h5>
138149
<input
139150
type="number"

app/create/gp/_components/bloatLimits.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
2+
13
export default function ConfigureBloatLimits({
24
mateHeight,
35
setMateHeight,
@@ -9,8 +11,9 @@ export default function ConfigureBloatLimits({
911
}) {
1012
return (
1113
<div className="mt-16">
12-
<h4 className="text-lg font-bold mb-4">
14+
<h4 className="flex items-center text-lg font-bold mb-4">
1315
{`Step ${nextStep - 1}: Configure Bloat Limits`}
16+
<TheoryTooltip id="bloatLimits" />
1417
</h4>
1518

1619
<div className="grid grid-cols-2 gap-4 align-top">

app/create/gp/_components/primitive.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { primitiveSetElements } from "@/app/_data/primitive";
2+
import TheoryTooltip from "@/app/_components/TheoryTooltip";
23

34
export default function ChoosePrimitiveSet({
45
currentStep,
@@ -9,8 +10,9 @@ export default function ChoosePrimitiveSet({
910
}) {
1011
return (
1112
<div className="my-4 mt-16">
12-
<h4 className="text-lg font-bold mb-4">
13+
<h4 className="flex items-center text-lg font-bold mb-4">
1314
Step 3: Choose Primitive Set Elements.
15+
<TheoryTooltip id="gpPrimitiveSet" />
1416
</h4>
1517
<div className="grid grid-cols-2 gap-4 align-top">
1618
{primitiveSetElements.map((element, index) => (

0 commit comments

Comments
 (0)