Java tutorial
/* * Copyright (c) 2015 by John Collins * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.powertac.customer.model; import static org.junit.Assert.*; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Date; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Instant; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powertac.common.Broker; import org.powertac.common.Competition; import org.powertac.common.RandomSeed; import org.powertac.common.Rate; import org.powertac.common.Tariff; import org.powertac.common.TariffSpecification; import org.powertac.common.TimeService; import org.powertac.common.config.Configurator; import org.powertac.common.enumerations.PowerType; import org.powertac.common.interfaces.ServerConfiguration; import org.powertac.common.repo.RandomSeedRepo; import org.powertac.common.repo.TariffRepo; import org.powertac.common.repo.TariffSubscriptionRepo; import org.powertac.common.repo.WeatherReportRepo; import org.springframework.test.util.ReflectionTestUtils; import com.joptimizer.optimizers.LPOptimizationRequest; import com.joptimizer.optimizers.LPPrimalDualMethod; import com.joptimizer.optimizers.OptimizationResponse; /** * @author jcollins */ public class LpTest { @Before public void setUp() throws Exception { } /** * Simple sanity test using the intended form. * */ @Test public void testSimpleLp() { } /** * Simple tariff eval example. * We ignore periodic charges, because those are handled by the * TariffEvaluator. We'll just use a simple TOU with daytime rates * (8:00-19:00) of 0.15 and night rates (20:00-7:00) of 0.09. * Example is 24 hours, starting at the beginning of a midnight * shift. The numbers are from the "idle" version of the * futureEnergyNeeds test, with an initial charge of 20 kwh. * end trk req max sur min total * 8 6 256 240 -16+20 236 * 16 8 0 240 240 236 * 0 0 192 240 32 428 * 8 6 256 240 -16 684 * We use 5 chargers, 6kW/charger, no battery count constraints, * 0.9 charge efficiency. */ @Test public void testLpTOU() { Date start = new Date(); int chargers = 5; double kW = 6.0; double eff = 0.9; int columns = 24; int shifts = 3; int rps = 2; // rows per shift int slackColumns = shifts * rps; double[] obj = { .09, .09, .09, .09, .09, .09, .09, .09, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .09, .09, .09, .09, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; assertEquals("correct size", columns + slackColumns, obj.length); // constraints: 1 row/timeslot + three rows/ShiftEnergy int rows = shifts * rps; double[][] a = new double[rows][columns + slackColumns]; double[] b = new double[rows]; // bounds: lb and ub per column double[] ub = new double[columns + slackColumns]; // should be max(chargers, batteries) double[] lb = new double[columns + slackColumns]; // max usage/timeslot Arrays.fill(ub, chargers * kW / eff); // min usage/timeslot Arrays.fill(lb, 0.0); // min & max usage per shift double[] req = { 240.0 / eff, 0.0, 192.0 / eff }; double[] cum = { 236.0 / eff, 236.0 / eff, 428.0 / eff }; for (int i = 0; i < shifts; i++) { // sum(p(t)) + slackI1 = min(req, max), t in shift for (int j = 0; j < 8; j++) { a[i * rps][i * 8 + j] = -1.0; a[i * rps][columns + i * rps] = -1.0; b[i * rps] = -req[i]; } // -sum(p(t)) + slackI2 = -total for (int j = 0; j < (i + 1) * 8; j++) { a[i * rps + 1][j] = -1.0; a[i * rps + 1][columns + i * rps + 1] = -1.0; b[i * rps + 1] = -cum[i]; } } LPOptimizationRequest or = new LPOptimizationRequest(); or.setC(obj); or.setA(a); or.setB(b); or.setLb(lb); or.setUb(ub); or.setDumpProblem(true); //optimization LPPrimalDualMethod opt = new LPPrimalDualMethod(); opt.setLPOptimizationRequest(or); try { int returnCode = opt.optimize(); assertEquals("success", OptimizationResponse.SUCCESS, returnCode); double[] sol = opt.getOptimizationResponse().getSolution(); Date end = new Date(); System.out.println("Duration = " + (end.getTime() - start.getTime())); System.out.println("Solution = " + Arrays.toString(sol)); } catch (Exception e) { fail(e.toString()); } } /** * Simple tariff eval example, constraints on running total only. * We ignore periodic charges, because those are handled by the * TariffEvaluator. We'll just use a simple TOU with daytime rates * (8:00-19:00) of 0.15 and night rates (20:00-7:00) of 0.09. * Example is 24 hours, starting at the beginning of a midnight * shift. The numbers are from the "idle" version of the * futureEnergyNeeds test, with an initial charge of 20 kwh. * end trk req max sur min total * 8 6 256 240 -16+20 236 * 16 8 0 240 240 236 * 0 0 192 240 32 428 * 8 6 256 240 -16 684 * We use 5 chargers, 6kW/charger, no battery count constraints, * 0.9 charge efficiency. */ @Test public void testLpTOU_Total() { Date start = new Date(); int chargers = 5; double kW = 6.0; double eff = 0.9; int columns = 24; int shifts = 3; int rps = 1; // rows per shift int slackColumns = shifts * rps; double[] obj = { .09, .09, .09, .09, .09, .09, .09, .09, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .15, .09, .09, .09, .09, 0.0, 0.0, 0.0 }; assertEquals("correct size", columns + slackColumns, obj.length); // constraints: 1 row/timeslot + one row/ShiftEnergy int rows = shifts * rps; double[][] a = new double[rows][columns + slackColumns]; double[] b = new double[rows]; // bounds: lb and ub per column double[] ub = new double[columns + slackColumns]; // should be max(chargers, batteries) double[] lb = new double[columns + slackColumns]; // max usage/timeslot Arrays.fill(ub, chargers * kW / eff); // min usage/timeslot Arrays.fill(lb, 0.0); // min & max usage per shift //double[] req = {240.0/eff, 0.0, 192.0/eff}; double[] cum = { 236.0 / eff, 236.0 / eff, 428.0 / eff }; for (int i = 0; i < shifts; i++) { // sum(p(t)) + slackI1 = min(req, max), t in shift // for (int j = 0; j < 8; j++) { // a[i * rps][i * 8 + j] = -1.0; // a[i * rps][columns + i * rps] = 1.0; // b[i * rps] = -req[i]; // } // -(sum(p(t)) + slackI2) = -total for (int j = 0; j < (i + 1) * 8; j++) { a[i * rps][j] = -1.0; } a[i * rps][columns + i * rps] = -1.0; b[i * rps] = -cum[i]; } LPOptimizationRequest or = new LPOptimizationRequest(); or.setC(obj); or.setA(a); or.setB(b); or.setLb(lb); or.setUb(ub); or.setDumpProblem(true); //optimization LPPrimalDualMethod opt = new LPPrimalDualMethod(); opt.setLPOptimizationRequest(or); try { int returnCode = opt.optimize(); assertEquals("success", OptimizationResponse.SUCCESS, returnCode); double[] sol = opt.getOptimizationResponse().getSolution(); Date end = new Date(); System.out.println("Duration = " + (end.getTime() - start.getTime())); System.out.println("Solution = " + Arrays.toString(sol)); } catch (Exception e) { fail(e.toString()); } } }