44#include < vector>
55#include < string>
66#include < algorithm>
7+ #include < set>
78#include " wash_opt.h"
89
910WashCrewOptimizer::WashCrewOptimizer ()
@@ -439,79 +440,95 @@ void WashCrewOptimizer::GroupSolutionMirrors(int hours)
439440 m_solution_data = solar_field_data ();
440441 m_solution_data.scale = hours * (m_settings.wash_rate / m_settings.heliostat_size );
441442 m_solution_data.groupings .clear ();
442-
443- std::vector<double > mirror_output = {};
444- std::vector<int > num_mirrors_by_group = {};
445- std::vector<int > new_assignments = { 0 };
443+ for (int t = 0 ; t < m_results.num_crews_by_period .size (); t++)
444+ m_results.solution_assignments [t] = {0 };
446445
447446
448- // determine the number of mirror groups;
449- int mirror_idx = 0 ;
450- double output = 0 ;
451- int group_idx = 0 ;
452- m_solution_data.groupings [group_idx] = {};
453- int num_assigned_mirrors;
454- for (int i = 0 ; i < m_results.num_vehicles ; i++)
455- { // i = wash crew index
456- num_assigned_mirrors = 0 ;
457- for ( // j = condensed data mirror group index
458- int j = 0 ;// m_results.assignments.at(i);
459- j < 0 ;// m_results.assignments.at(i + 1);
460- j++
461- )
447+ // detremine the breakpoints that may be the end of a crew's assignment.
448+ std::set<int > assignment_breaks = {};
449+ if (m_settings.use_uniform_assignment )
450+ for (int t = 0 ; t < m_results.num_crews_by_period .size (); t++)
451+ for (int c = 0 ; c < m_results.num_crews_by_period .at (t); c++)
452+ assignment_breaks.insert ((int )(
453+ m_solar_data.num_mirrors
454+ * c / m_results.num_crews_by_period .at (t)
455+ + 0.5
456+ ));
457+ else
458+ for (int t = 0 ; t < m_results.num_crews_by_period .size (); t++)
459+ for (int c = 0 ; c < m_results.num_crews_by_period .at (t); c++)
460+ assignment_breaks.insert ((int )(
461+ GetNumberOfMirrors (
462+ m_results.assignments_by_crews [m_results.num_crews_by_period .at (t)].at (c),
463+ m_results.assignments_by_crews [m_results.num_crews_by_period .at (t)].at (c+1 )
464+ )));
465+
466+ // Add the hourly breaks.
467+ for (int c = 0 ; c <= m_solar_data.num_mirrors ; c += m_solution_data.scale )
468+ assignment_breaks.insert (c);
469+
470+ // Create a vector consisting of all the elemnents of the set
471+ // (which are unique and ordered).
472+ m_solution_data.num_mirror_groups = assignment_breaks.size ();
473+ m_solution_data.num_mirrors_by_group = new int [assignment_breaks.size () - 1 ];
474+ m_solution_data.mirror_output = new double [assignment_breaks.size () - 1 ];
475+ // std::vector<int> breakpoints = {};
476+ // for (int c : assignment_breaks)
477+ // breakpoints.push_back(c);
478+ int idx = 0 ;
479+ int m;
480+ for (int c : assignment_breaks)
481+ {
482+ if (c != 0 )
462483 {
463- for (int k = 0 ; k < m_condensed_data.num_mirrors_by_group [j]; k++)
464- { // k = mirror index within condensed data
465- output += m_solar_data.mirror_output [mirror_idx];
466- m_solution_data.groupings [group_idx].push_back (m_solar_data.names [mirror_idx]);
467- num_assigned_mirrors++;
468- mirror_idx++;
469- if (num_assigned_mirrors == m_solution_data.scale )
470- {
471- mirror_output.push_back (output);
472- num_mirrors_by_group.push_back (num_assigned_mirrors);
473- num_assigned_mirrors = 0 ;
474- output = 0 .;
475- group_idx++;
476- m_solution_data.groupings [group_idx] = {};
477- }
484+ m_solution_data.num_mirrors_by_group [idx] = c - m;
485+ }
486+ m = c;
487+ idx++;
488+ }
489+
490+ // assign mirrors to the groups, and update assignments as breakpoints are hit.
491+ int cumulative_mirrors = 0 ;
492+ int solar_data_idx = 0 ;
493+ int solar_mirrors = m_solar_data.num_mirrors_by_group [0 ];
494+ int solution_mirrors;
495+ double sol_group_output;
496+ for (int solution_idx = 0 ; solution_idx < assignment_breaks.size () - 1 ; solution_idx++)
497+ {
498+ solution_mirrors = m_solution_data.num_mirrors_by_group [solution_idx]*1 ;
499+ sol_group_output = 0 .;
500+ while (solution_mirrors > 0 )
501+ {
502+ if (solution_mirrors < solar_mirrors)
503+ {
504+ sol_group_output += m_solar_data.mirror_output [solar_data_idx] * (double )solution_mirrors / m_solar_data.num_mirrors_by_group [solar_data_idx];
505+ cumulative_mirrors += solution_mirrors;
506+ solar_mirrors -= solution_mirrors;
507+ solution_mirrors = 0 ;
508+ }
509+ else
510+ {
511+ sol_group_output += m_solar_data.mirror_output [solar_data_idx] * (double )solar_mirrors / m_solar_data.num_mirrors_by_group [solar_data_idx];
512+ cumulative_mirrors += solar_mirrors;
513+ solution_mirrors -= solar_mirrors;
514+ solar_data_idx++;
515+ solar_mirrors = m_solar_data.num_mirrors_by_group [solar_data_idx];
478516 }
479517 }
480- if (num_assigned_mirrors > 0 )
518+ m_solution_data.mirror_output [solution_idx] = sol_group_output;
519+ for (int t = 0 ; t < m_results.num_crews_by_period .size (); t++)
481520 {
482- mirror_output.push_back (output);
483- num_mirrors_by_group.push_back (num_assigned_mirrors);
484- num_assigned_mirrors = 0 ;
485- output = 0 .;
486- group_idx++;
487- m_solution_data.groupings [group_idx] = {};
521+ if (
522+ std::find (
523+ m_results.assignments_by_crews .at (m_results.num_crews_by_period .at (t)).begin (),
524+ m_results.assignments_by_crews .at (m_results.num_crews_by_period .at (t)).end (),
525+ cumulative_mirrors
526+ )
527+ != m_results.assignments_by_crews .at (m_results.num_crews_by_period .at (t)).end ()
528+ )
529+ m_results.solution_assignments [t].push_back (solution_idx);
488530 }
489- new_assignments.push_back (group_idx);
490531 }
491- /*
492- std::cerr << "Path: ";
493- for (int j = 0; j < m_results.assignments.size(); j++)
494- {
495- std::cerr << m_results.assignments.at(j) << ",";
496- }
497- std::cerr << "\n";
498- for (int i = 0; i < group_idx; i++)
499- {
500- std::cerr << "Group " << i << " num mirrors: "
501- << num_mirrors_by_group[i]
502- << " power: " << mirror_output[i] << "\n";
503- }
504- */
505- m_solution_data.num_mirrors_by_group = new int [num_mirrors_by_group.size ()]; &num_mirrors_by_group[0 ];
506- m_solution_data.mirror_output = new double [mirror_output.size ()];
507- for (size_t i = 0 ; i < mirror_output.size (); i++)
508- {
509- m_solution_data.mirror_output [i] = mirror_output.at (i);
510- m_solution_data.num_mirrors_by_group [i] = num_mirrors_by_group.at (i);
511- }
512- m_solution_data.total_mirror_output = m_condensed_data.total_mirror_output *1.0 ;
513- m_solution_data.num_mirror_groups = mirror_output.size ();
514- // m_results.assignments = new_assignments;
515532}
516533
517534void WashCrewOptimizer::CalculateRevenueAndCosts ()
@@ -959,6 +976,7 @@ void WashCrewOptimizer::OptimizeWashCrews(int scale, bool output)
959976 double cost, cost_eq;
960977 double field_eff, field_eff_eq;
961978 double min_cost = INFINITY;
979+ int cum_mirrors;
962980 for (int i = 1 ; i <= m_settings.max_num_crews ; i++)
963981 {
964982 path = RetracePath (
@@ -978,10 +996,18 @@ void WashCrewOptimizer::OptimizeWashCrews(int scale, bool output)
978996 std::cerr << "\nAverage field efficiency: " << field_eff << "\n";
979997 */
980998 // use the equal-assignment path if specified; otherwise, use DP output.
999+
1000+ m_results.assignments_by_crews [i] = {0 };
1001+ for (int c = 0 ; c < path.size ()-1 ; c++)
1002+ m_results.assignments_by_crews [i].push_back (
1003+ GetNumberOfMirrors (path[c], path[c + 1 ])
1004+ );
9811005 m_results.assignments_by_crews [i] = path;
9821006 for (int t = 0 ; t < 12 ; t++)
9831007 {
984- rev_losses[int_pair_to_string (i, t+1 )] = cost * m_solar_data.dni_by_period .at (t);
1008+ rev_losses[int_pair_to_string (i, t+1 )] = (
1009+ cost * m_solar_data.dni_by_period .at (t)
1010+ );
9851011 }
9861012 }
9871013 }
0 commit comments