title: What is the best optimization function for this multi-objective problem?
body: <p>Currently I am working on a optimalization problem in Python. I hope this is the right place to post,because I think the question has more to do with the math than the actual coding.</p>
  <p>The context:</p>
  <p>There is a whole group of students. The students have different characteristics.</p>
  <ul>
  <li>Social skills</li>
  <li>Motivation</li>
  <li>Discipline</li>
  <li>Intelligence</li>
  </ul>
  <p>In addition, each students gets a relative score on the variables:</p>
  <ul>
  <li>alpha</li>
  <li>beta</li>
  <li>gamma</li>
  </ul>
  <p>Lastly, each student needs support from a teacher, but some more than the others. Therefore, a cost parameter is introduced. The 'worth' of a student is determined as follows:</p>
  <p>$potential  = \frac{(0.2 * socialskills + 0.3 * motivation + 0.4 * discipline + 0.1 * intelligence)}{costs}$</p>
  <p>The goal is to find a group of the best $n$ students, but the with the characteristics alpha, beta and gamma evenly distributed. This is a multi-objective optimalization problem.</p>
  <p>Important to note here, on a personal level, I have a background in engineering and I have had no formal training on mathematical optimalization. If there happens to be a mathematical more sound way, I am happy to learn.</p>
  <p>The following blocks are just to generate the data. In the first block I create the student</p>
  <pre><code>class Student:
      def __init__(self, alpha, beta, gamma, social_skills, motivation, discipline, intelligence, costs):
          potential  = 0.2 * social_skills + 0.3 * motivation + 0.4 * discipline + 0.1 * intelligence
          self.alpha_relative = alpha/(alpha+beta+gamma)
          self.beta_relative = beta/(alpha+beta+gamma)
          self.gamma_relative = gamma/(alpha+beta+gamma)
          self.ratio = potential / costs 
  </code></pre>
  <p>This is also part of the data generation. Here I create a list of student objects.</p>
  <pre><code>def create_student_list(num_students):
      
      list_students = []
      
      for i in range(num_students):
          #define the student characteristics 
          alpha = r.randint(1,10)
          beta = r.randint(1,10)
          gamma = r.randint(1,10)
          social_skills = r.randint(1,10)
          motivation = r.randint(1,10)
          discipline = r.randint(1,10)
          intelligence = r.randint(1,10)
          costs = r.randint(1,2)
  
          #create student objects
          student = Student(alpha, beta, gamma, social_skills, motivation, discipline, intelligence, costs)
  
          #append objects to a list
          list_students.append(student)
          
      return list_students
  </code></pre>
  <p>Now the actual work begins. I take a random sample of students, which form a group.I add up their 'worth' in the variable 'ratio_sum'.</p>
  <pre><code>def create_group(students, group_size):
      #create array of random intergers to pick students randomly 
      num_students = len(students)
      random_pick = r.sample(range(0,num_students),group_size)
      
      #initate variables 
      ratio_sum = 0
      alpha_sum = 0
      beta_sum  = 0
      gamma_sum = 0
      
      #calculate the characteristics of the group
  
      for j in random_pick:
          ratio_sum += students[j].ratio
          alpha_sum += students[j].alpha_relative
          beta_sum  += students[j].beta_relative
          gamma_sum += students[j].gamma_relative
  
      var = np.var([alpha_sum, beta_sum, gamma_sum])
  
      return random_pick, ratio_sum, var
  </code></pre>
  <p>I also compute the alpha, beta, gamma score of the group. Because the goal is have a diverse group I calculate the variance of the array:</p>
  <pre><code>[alpha_sum, beta_sum, gamma_sum]
  </code></pre>
  <p>In the last function the actual simulation is performed. For testing purposes I did the simulation only 10 times and formed groups of 3 students.</p>
  <pre><code>def simulate(num_simulations, students, group_size):
      simulation = []
      for i in range(num_simulations):
          simulation.append(create_group(students, group_size))    
      return simulation
      
  </code></pre>
  <p>In the output, the first index of each line is the sample index. The second index is the total 'worth'. The last index is the variance.</p>
  <pre><code>[([4, 7, 2], 16.799999999999997, 0.06279772521858522),
   ([5, 3, 0], 11.0, 0.14400476660092046),
   ([9, 6, 4], 14.2, 0.04469349176343509),
   ([6, 0, 4], 13.05, 4.139179301210081e-05),
   ([8, 0, 2], 14.85, 0.015072541362223899),
   ([3, 1, 8], 15.8, 0.15864323507180644),
   ([4, 8, 3], 15.600000000000001, 0.061507936507936546),
   ([4, 3, 5], 14.250000000000002, 0.08901065357109311),
   ([5, 9, 4], 13.649999999999999, 0.03338968723584108),
   ([1, 3, 0], 15.55, 0.053101851851851845)]
  </code></pre>
  <p>One of these lines is the optimal solution. But here I start to reach the limits of my knowlegde.</p>
  <p>First question: is it okay to use the variance as a measure of how equal the groups are in terms of alpha, beta and gamma?</p>
  <p>Second question: I want to maximize the worth/cost ratio and minimize the variance. What is the best approach? I find it rather difficult, because the variance is of different order than the ratio, so in the (to be determined) optimization function, how do I pick the constants such that both parameters are equally important or the other is $x$ times more important than the other?</p>
  <p>A whole story, but I hope somebody could advice me on the best way to proceed.</p>
  <p>Thank you,
  Tim</p>