Skip to content

Commit

Permalink
feat(marxan-run): most-different dummy detection
Browse files Browse the repository at this point in the history
  • Loading branch information
kgajowy committed Jul 21, 2021
1 parent 4166844 commit ee82915
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { ResultRow } from '@marxan/marxan-output';
import { MostDifferentService } from './most-different.service';
import { Test } from '@nestjs/testing';

let sut: MostDifferentService;

beforeEach(async () => {
const sandbox = await Test.createTestingModule({
providers: [MostDifferentService],
}).compile();
sut = sandbox.get(MostDifferentService);
});

describe(`when given result rows`, () => {
it(`marks those with most different under particular criteria`, () => {
expect(sut.map(subjectRows)).toMatchInlineSnapshot(`
Array [
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 5,
"missingValues": 0,
"mostDifferent": true,
"mpm": 0,
"penalty": 0,
"planningUnits": 4,
"runId": 1,
"score": 1000,
"shortfall": 0,
},
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 200,
"missingValues": 0,
"mostDifferent": true,
"mpm": 0,
"penalty": 0,
"planningUnits": 5,
"runId": 2,
"score": 1000,
"shortfall": 0,
},
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 50,
"missingValues": 0,
"mostDifferent": false,
"mpm": 0,
"penalty": 0,
"planningUnits": 1,
"runId": 3,
"score": 1000,
"shortfall": 0,
},
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 50,
"missingValues": 0,
"mostDifferent": true,
"mpm": 0,
"penalty": 0,
"planningUnits": 14,
"runId": 4,
"score": 1000,
"shortfall": 0,
},
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 75,
"missingValues": 0,
"mostDifferent": false,
"mpm": 0,
"penalty": 0,
"planningUnits": 4,
"runId": 5,
"score": 1000,
"shortfall": 0,
},
Object {
"best": false,
"connectivity": 0,
"connectivityEdge": 0,
"connectivityIn": 0,
"connectivityInFraction": 0,
"connectivityOut": 0,
"connectivityTotal": 0,
"cost": 95,
"missingValues": 0,
"mostDifferent": false,
"mpm": 0,
"penalty": 0,
"planningUnits": 4,
"runId": 6,
"score": 1400,
"shortfall": 0,
},
]
`);
});
});

const defaults = (): Omit<
ResultRow,
'runId' | 'score' | 'cost' | 'planningUnits'
> => ({
connectivity: 0,
connectivityTotal: 0,
connectivityIn: 0,
connectivityEdge: 0,
connectivityOut: 0,
connectivityInFraction: 0,
penalty: 0,
shortfall: 0,
missingValues: 0,
mpm: 0,
best: false,
mostDifferent: false,
});

const subjectRows: ResultRow[] = [
{
runId: 1,
score: 1000,
cost: 5,
planningUnits: 4,
...defaults(),
},
{
runId: 2,
score: 1000,
cost: 200,
planningUnits: 5,
...defaults(),
},
{
runId: 3,
score: 1000,
cost: 50,
planningUnits: 1,
...defaults(),
},
{
runId: 4,
score: 1000,
cost: 50,
planningUnits: 14,
...defaults(),
},
{
runId: 5,
score: 1000,
cost: 75,
planningUnits: 4,
...defaults(),
},
{
runId: 6,
score: 1400,
cost: 95,
planningUnits: 4,
...defaults(),
},
];
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import { Injectable } from '@nestjs/common';
import { maxBy, minBy } from 'lodash';
import { ResultRow } from '@marxan/marxan-output';
import { isDefined } from '@marxan/utils';

@Injectable()
export class MostDifferentService {
map(fromState: ResultRow[]): ResultRow[] {
return fromState;
const highestCostPerScore = minBy(fromState, (e) => e.cost / e.score);
const lowestCostPerScore = maxBy(fromState, (e) => e.cost / e.score);
const withHighestPuIncluded = maxBy(fromState, (e) => e.planningUnits);
const mostDifferent = [
highestCostPerScore?.runId,
lowestCostPerScore?.runId,
withHighestPuIncluded?.runId,
].filter(isDefined);
return fromState.map((row) =>
Object.assign<ResultRow, Pick<ResultRow, 'mostDifferent'>>(row, {
mostDifferent: mostDifferent.includes(row.runId),
}),
);
}
}

0 comments on commit ee82915

Please sign in to comment.