Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin committed Jan 14, 2025
2 parents 3d43a46 + fe98dcc commit 1fd9426
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
8 changes: 4 additions & 4 deletions client/src/pages/submission-summary/table/SummaryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Button,
capitalize,
Chip,
CircularProgress,
Collapse,
Divider,
Stack,
Expand Down Expand Up @@ -262,10 +263,9 @@ export default function Table({ apiKey }: { apiKey?: string | number }) {
/>
),
queued: (
<HourglassEmptyOutlined
color="primary"
fontSize="small"
/>
<Stack sx={{ alignItems: "center" }}>
<CircularProgress size={24} />
</Stack>
),
}[submission?.validation?.outcome] ?? (
<HourglassEmptyOutlined
Expand Down
27 changes: 13 additions & 14 deletions packages/validator/src/checks/checkImmediateCollision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@ export function checkImmediateCollision({
next,
timestep,
}: CheckParameters): CheckResult {
const a = next.map($);
const hasCollision = new Set(a).size !== a.length;
if (!hasCollision) return {};
const collision = _(next)
.map((c, i) => [c, i] as const)
.groupBy(([c, i]) => $(c))
.groupBy(([c]) => $(c))
.values()
.find((agents) => agents.length > 1)
.value();
if (collision) {
const [p] = head(collision);
return {
errorAgents: collision.map(([, i]) => i),
errors: [
`agent-to-agent direct collision, agents ${collision
.map(([, i]) => i)
.join(" and ")}, at timestep ${timestep} ${$(p)}`,
],
};
} else {
return {};
}
const [p] = head(collision);
return {
errorAgents: collision.map(([, i]) => i),
errors: [
`agent-to-agent direct collision, agents ${collision
.map(([, i]) => i)
.join(" and ")}, at timestep ${timestep} ${$(p)}`,
],
};
}
22 changes: 22 additions & 0 deletions packages/validator/src/encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,25 @@ export function encode(input: string): string {

return encoded;
}

/**
* From ChatGPT
* Run length decoder
*/
export function decode(encoded: string): string {
let decoded = "";
let count = "";

for (const char of encoded) {
if (isNaN(Number(char))) {
// If the character is not a number, append it 'count' times to the result
decoded += char.repeat(Number(count) || 1);
count = ""; // Reset count for the next sequence
} else {
// If the character is a number, add it to the count
count += char;
}
}

return decoded;
}
18 changes: 16 additions & 2 deletions packages/validator/src/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DoneException } from "./exceptions/DoneException";
import type { Dictionary } from "lodash";
import { some, zip } from "lodash";
import { checkEdgeCollision } from "./checks/checkEdgeCollision";
import { decode } from "./encode";

type ValidationParameters = {
paths: string[];
Expand Down Expand Up @@ -52,6 +53,18 @@ export function processAgent(agent: string) {
};
}

export function processAgentSimple(agent: string) {
const decoded = decode(agent);
return {
seek: (n: number) => {
return decoded[n] || "w";
},
done: (n: number) => {
return n >= decoded.length;
},
};
}

export const defaultOffsetMap = {
u: { x: 0, y: -1 },
d: { x: 0, y: 1 },
Expand Down Expand Up @@ -84,12 +97,13 @@ export function validate({
onFinish = [],
onError = () => false,
}: ValidationParameters) {
const as = paths.map(processAgent);
const as = paths.map(processAgentSimple);
let i = 0;
let prev = sources;
while (some(as, (c) => !c.done(i))) {
const actions = createActionMap(i, as);
const next = sumPositions(prev, createOffsetMap(actions));
const done = as.map((c) => c.done(i));
for (const check of onTimestep) {
const result = check({
timestep: i,
Expand All @@ -99,7 +113,7 @@ export function validate({
domain,
sources,
goals,
done: as.map((c) => c.done(i)),
done,
});
// Stop validation if onError returns true.
if (result.errors?.length && onError(result)) return false;
Expand Down
1 change: 1 addition & 0 deletions server/src/models/OngoingSubmission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const schema = createSchema(
solutions: [String],
options: { skipValidation: Schema.Types.Boolean },
validation: {
timeTaken: Number,
isValidationRun: Schema.Types.Boolean,
errors: [String],
outcome: String,
Expand Down
2 changes: 1 addition & 1 deletion server/src/validation/submissionRequestValidatorWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ const submitOne = async (
instance: data.instance.id,
lowerBound: data.lower_cost,
cost: data.solution_cost,
solutions: data.solution_plan,
solutions: data.solution_plan.map(encode),
options: { skipValidation: data.skip_validation },
}).save();

Expand Down
12 changes: 8 additions & 4 deletions server/src/validation/submissionValidatorWorker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { chain, each, isInteger, isNumber, max, min, once } from "lodash";
import { chain, each, isInteger, isNumber, max, min, now, once } from "lodash";
import { context } from "logging";
import { Infer, Instance, Map, OngoingSubmission, Scenario } from "models";
import { Document, Types } from "mongoose";
Expand Down Expand Up @@ -88,7 +88,8 @@ async function getMeta(instanceId: Types.ObjectId) {

async function saveResults(
submission: OngoingSubmissionDocument,
errors: string[]
errors: string[],
meta: { timeTaken: number }
) {
log.info("Saving results");
for (const outdated of await OngoingSubmission.find({
Expand All @@ -109,6 +110,7 @@ async function saveResults(
errors,
isValidationRun: true,
outcome: (errors.length ? "invalid" : "valid") satisfies Outcome,
...meta,
} satisfies OngoingSubmission[typeof validationResultsKey])
.save();
log.info("Results saved");
Expand Down Expand Up @@ -145,7 +147,7 @@ async function validateGroup({
const errorAgents: number[][] = [];

const [updateSolutionCost, , realCost] = createSolutionCostChecker();

const timeStart = now();
validate({
domain: { cells, width, height },
paths: submission.solutions.map((s) => s || "w"),
Expand All @@ -166,14 +168,16 @@ async function validateGroup({
},
});

const timeTaken = now() - timeStart;

// Update solution cost based on validation results
// TODO: Refactor for immutability
await setSolutionCost(submission, realCost.current, errors);

logOutcome(errors, errorAgents, mode);

// Don't have to wait to save results
saveResults(submission, errors);
saveResults(submission, errors, { timeTaken });
return { errors };
}

Expand Down

0 comments on commit 1fd9426

Please sign in to comment.