Skip to content

Commit

Permalink
#1076 - Update usage of inertia in tariff evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
jecollins committed Apr 12, 2021
1 parent 94c5443 commit f80b9d1
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ public Map<String, Map<String, StructureInstance>> getStructures ()
return structures;
}

/**
* Retrieves structures of the specified type
*/
public Map<String, StructureInstance> getSpecifiedStructures (String type)
{
return getStructures().get(type);
}

/**
* Singleton accessor
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2018 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -133,11 +133,11 @@ public void initialize (FactoredCustomerService service,

Config config = Config.getInstance();
Map<String, StructureInstance> subscribers =
config.getStructures().get("TariffSubscriberStructure");
config.getSpecifiedStructures("TariffSubscriberStructure");
Map<String, StructureInstance> optimizers =
config.getStructures().get("ProfileOptimizerStructure");
config.getSpecifiedStructures("ProfileOptimizerStructure");
Map<String, StructureInstance> capacities =
config.getStructures().get("CapacityStructure");
config.getSpecifiedStructures("CapacityStructure");

subscriberStructure =
(TariffSubscriberStructure) subscribers.get(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public void evaluateTariffs ()
.getInertiaDistribution().drawSample());
}
else {
// WARNING: magic number here
log.warn("no inertia distro, using default value 0.7");
evaluator.withInertia(0.7);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<count>3</count>
<population>3</population>
<type>THERMAL_STORAGE_CONSUMPTION</type>
<customerSize>LARGE</customerSize>
<customerSize>LARGE</customerSize>
<multiContracting>true</multiContracting>
<canNegotiate>false</canNegotiate>
<controllableKW>-500</controllableKW>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class TariffEvaluator
private TariffEvaluationHelper helper;

// per-customer parameter settings
private int chunkSize = 1; // max size of allocation chunks
private int chunkSize = 50; // min size of allocation chunks
private int maxChunkCount = 200; // max number of chunks
private int tariffEvalDepth = 5; // # of tariffs/powerType to eval
private double inertia = 0.8;
Expand Down Expand Up @@ -186,8 +186,8 @@ public void initializeRegulationFactors (double expectedCurtailment,

// parameter settings
/**
* Sets the target size of allocation chunks. Default is 1. Actual
* chunk size will be at least 0.5% of the population size.
* Sets the target size of allocation chunks. Default is 50. Actual
* chunk size will be at least population / maxChunkCount.
*/
public TariffEvaluator withChunkSize (int size)
{
Expand All @@ -198,6 +198,18 @@ public TariffEvaluator withChunkSize (int size)
return this;
}

/**
* Sets the maximum number of allocation chunks for a given population.
*/
public TariffEvaluator withMaxChunkCount (int count)
{
if (count > 0)
maxChunkCount = count;
else
log.error("max chunk count " + count + " < 0");
return this;
}

/**
* Sets the number of tariffs/broker of each applicable PowerType
* to consider. Default is 5, which means that only the 5 most recent
Expand Down Expand Up @@ -346,6 +358,8 @@ public void evaluateTariffs ()

// adjust inertia for BOG, accounting for the extra
// evaluation cycle at ts 0
// TODO - This should not be computed per evaluator, but rather at the class level.
// See Issue #1078
double actualInertia =
Math.max(0.0,
(1.0 - Math.pow(2, 1 - evaluationCounter)) * inertia);
Expand Down Expand Up @@ -457,8 +471,8 @@ private void evaluateAlternativeTariffs (TariffSubscription current,

// Compute the final cost number for each tariff
HashMap<Tariff, EvalData> costs = new HashMap<Tariff, EvalData>();
double signupCost = 0.0;
for (Tariff tariff: tariffs) {
double signupCost;
EvalData eval = evaluatedTariffs.get(tariff);
double inconvenience = eval.inconvenience;
double cost = eval.costEstimate;
Expand Down Expand Up @@ -542,24 +556,33 @@ private void evaluateAlternativeTariffs (TariffSubscription current,
// For large populations, we do it in chunks.
chunk = getChunkSize(population);
}
double signupCost = currentTariff.getSignupPayment();
double adjustedInertia = inertia;
while (remainingPopulation > 0) {
int count = (int)Math.min(remainingPopulation, chunk);
remainingPopulation -= count;
// allocate a chunk
double inertiaSample = accessor.getInertiaSample();
if (!revoked && withdraw0 <= 0.0 &&
signupCost <= 0.0 && inertiaSample < inertia) {
// skip this one if not processing revoked tariff,
// or if there is no payment possible from withdrawing,
// or if the customer was not induced by a positive signup cost,
// or if the customer is not paying attention.
// skip this chunk if
// the current tariff is not revoked,
// and there is not a positive payment possible from withdrawing,
// and the customer was not induced by a positive signup cost
// and the customer is not paying attention
continue;
}
else if (signupCost > 0.0 &&
inertiaSample < inertia * signupBonusFactor) {
// Use lower inertia in case the current tariff had a signup bonus
continue;
if (signupCost > 0.0) {
// ff there was a positive signup cost, customers are suspicious
adjustedInertia *= signupBonusFactor;
}
if (count > 1) {
// for a population, we apply inertia by subdividing the population
count = (int)Math.round((double)count * (1.0 - adjustedInertia));
}
else if (inertiaSample < adjustedInertia)
continue;

double tariffSample = accessor.getTariffChoiceSample();
// walk down the list until we run out of probability
boolean allocated = false;
Expand Down Expand Up @@ -811,14 +834,20 @@ public double computeInconvenience (Tariff tariff)
}

// returns the correct chunk size for a given population
private int getChunkSize (int population)
int getChunkSize (int population)
{
if (population <= chunkSize)
return population;
else
return Math.max(population / maxChunkCount, chunkSize);
}

// test support
HashMap<Tariff, Integer> getAllocations ()
{
return allocations;
}

// Spring component access ------------------------------------------
private TariffRepo getTariffRepo ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ private void initSubscription (TariffSubscription sub)
}

// ------------------------- tests -----------------------------

/**
* Verify chunk size calculation
*/
@Test
public void chunkSizeDefaults ()
{
assertEquals(50, evaluator.getChunkSize(10000));
assertEquals(50, evaluator.getChunkSize(8000));
assertEquals(60, evaluator.getChunkSize(12000));
assertEquals(30, evaluator.getChunkSize(30));
}

/**
* Test for no new tariffs case.
*/
Expand All @@ -178,14 +191,17 @@ public void noTariffTest ()

evaluator.withChunkSize(5000); // just two chunks
evaluator.evaluateTariffs();
HashMap<Tariff, Integer> alloc = evaluator.getAllocations();
assertEquals(0, alloc.size(), "no allocations");

}

@Test
public void testScaleFactor ()
{
assertEquals((7 * 24.0) / 48.0, evaluator.getScaleFactor(), 1e-6, "default scale factor");
assertEquals((7 * 24.0) / 48.0, evaluator.getScaleFactor(), 1e-6, "default scale factor 1");
evaluator.setProfileLength(14 * 24);
assertEquals((14 * 24.0) / 48.0, evaluator.getScaleFactor(), 1e-6, "default scale factor");
assertEquals((14 * 24.0) / 48.0, evaluator.getScaleFactor(), 1e-6, "default scale factor 2");
}

@Test
Expand Down Expand Up @@ -905,9 +921,9 @@ public Object answer(InvocationOnMock invocation) {
evaluator.withChunkSize(50); // 200 chunks
evaluator.evaluateTariffs();
assertEquals(3, calls.size(), "three tariffs");
assertEquals(-5000, calls.get(defaultConsumption).intValue(), "-5000 for default");
assertEquals(2500, calls.get(bobTariff).intValue(), "+2500 for bob");
assertEquals(2500, calls.get(jimTariff).intValue(), "+2500 for jim");
assertEquals(-3000, calls.get(defaultConsumption).intValue(), "-5000 for default");
assertEquals(1500, calls.get(bobTariff).intValue(), "+2500 for bob");
assertEquals(1500, calls.get(jimTariff).intValue(), "+2500 for jim");
}

// Test min contract duration. Two tariffs from Jim have equal signup
Expand Down

0 comments on commit f80b9d1

Please sign in to comment.